为什么要避免在JavaScript中创建原语对象?
我正在关注一个关于W3Schools的JavaScript教程。在阅读几乎每一页的内容时,他们会提醒用户“避免创建对象”,而是使用基本数据类型。他们给出了这样的理由,因为“如果使用对象,代码将变得难以理解,或者执行速度将降低”。我们是否应该避免在JavaScript中创建对象 例如:为什么要避免在JavaScript中创建原语对象?,javascript,Javascript,我正在关注一个关于W3Schools的JavaScript教程。在阅读几乎每一页的内容时,他们会提醒用户“避免创建对象”,而是使用基本数据类型。他们给出了这样的理由,因为“如果使用对象,代码将变得难以理解,或者执行速度将降低”。我们是否应该避免在JavaScript中创建对象 例如: var value = new Number(1); // Avoid this var value = 1; // do something like this instead. “
var value = new Number(1); // Avoid this
var value = 1; // do something like this instead.
“避免创建对象”这句话本身在JavaScript中是荒谬的,因为JavaScript到处都有对象,是现存最面向对象的语言之一。但是“避免创建原语的对象版本”是有效的,您引用的代码就是这样做的。也就是说,避免使用新字符串
,新数字
,以及新布尔值
JavaScript包含字符串、数字和布尔值的基本版本和对象版本。几乎没有任何理由显式地创建它们中任何一个的对象版本,这样做确实会导致混乱;请参阅内联注释:
var s1、s2、n1、n2;
//这些都是错误的,因为使用==,对象永远不等于非对象
s1=新字符串(“hi”);
s2=“你好”;
console.log(s1==s2);//假的
n1=新编号(42);
n2=42;
console.log(n1==n2);//也是假的
//这是错误的,因为即使使用==,两个*不同*的对象也永远不相等
//(即使它们相等)
s1=新字符串(“什么…”);
s2=新字符串(“什么…”);
console.log(s1==s2);//也是假的
n1=新编号(42);
n2=新编号(42);
console.log(n1==n2);//同样为false
它改变了运算符处理数字、字符串和布尔值的直观方式:
- 当构造任何数字时,严格比较(
)会中断,因此==
为真,而42===42
为假42===new Number(42)
- 当两个数字都是对象时,抽象比较(
)中断,因此=
为真,而42==新数字(42)
为假新数字(42)==新数字(42)
- 当构造数字时,
运算符给出不同的结果,因此typeof
是typeof(42)
,而number
是typeof(新数字(42))
对象
- 当转换为布尔值时,
为false,但0
为true,因此以下两个将具有不同的行为:newnumber(0)
var a=0;
如果(a)
控制台日志(“非零”);
其他的
console.log(“零!”);//“零!”
var b=新编号(0);
如果(b)
console.log(“非零”);//“不是零”
其他的
log(“零!”)代码>w3schools.com是出了名的穷。要获得适当的信息,请查看其他地方,例如。也就是说,创建原语的对象版本几乎没有必要或不合适。在您提供的示例中,使用构造函数有点难理解。但是,随着代码变得越来越复杂,不使用对象就有点不可能了。而且,我发现w3schools的信息也不是很好。我建议查看MDN()以获得更深入的文档。虽然如果你只是把w3schools作为一个起点,这可能是可以理解的。@Jone Dotosvky在这里读过一篇文章,原因之一可能是代码优化和readability@FlyingGambit我打赌此刻你甚至都没读过网站上的内容。回答得很好!另一个与之相关的是这个
在非严格模式和严格模式下将原语传递给函数上下文时的行为。类似这样的内容:函数强制(){返回此;};强制调用的类型(5)=“对象”/*非严格模式*/typeof强制调用(5)=“数字”/*严格模式*/
我只是说它是相关的,因为它是一种在非严格模式下保存对临时对象的引用的方法。例如,您可以将该函数分配给原型以执行此操作:Number.prototype.concure=concure;5.胁迫代码>给定var q=foo;var r=q.toUpperCase()
与识别模式并将原始字符串提供给案例转换函数相比,一个体面的实现是否有任何理由会费心创建一个对象?@supercat:如果string.prototype.toUpperCase
仍然是引擎在启动时给出的原始值,我就不知道了。事实上,如果他们不这样做,我会相当惊讶(但有时我会相当惊讶)构造函数中的代码>。这是多余的,省略它有助于开发人员使用构造函数更快地进行调试,因为banana
将等于undefined
,而不是window
。另一个需要考虑的是,您的示例假定了非严格模式而不是严格模式,其中函数将抛出错误<代码>不能设置未定义的< /代码>的“属性”颜色,因为由于缺少<代码> new < /> >没有定义上下文。JS中的new运算符初始化空对象={},这就是为什么比较失败的原因。“在没有new
关键字的情况下调用时,this
将成为全局对象,导致副作用。”仅在松散模式下,不应使用。在严格模式下(从ES5开始提供),当调用Fruit()
时,Fruit
中的将未定义,因此此.color
将是一个错误。另外,从ES2015开始,如果您使用class
语法,Foo
将是一个类构造函数,并且调用那些没有new
的构造函数会有自己的特定错误。