为什么要避免在JavaScript中创建原语对象?

为什么要避免在JavaScript中创建原语对象?,javascript,Javascript,我正在关注一个关于W3Schools的JavaScript教程。在阅读几乎每一页的内容时,他们会提醒用户“避免创建对象”,而是使用基本数据类型。他们给出了这样的理由,因为“如果使用对象,代码将变得难以理解,或者执行速度将降低”。我们是否应该避免在JavaScript中创建对象 例如: var value = new Number(1); // Avoid this var value = 1; // do something like this instead. “

我正在关注一个关于W3Schools的JavaScript教程。在阅读几乎每一页的内容时,他们会提醒用户“避免创建对象”,而是使用基本数据类型。他们给出了这样的理由,因为“如果使用对象,代码将变得难以理解,或者执行速度将降低”。我们是否应该避免在JavaScript中创建对象

例如:

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))
    对象
  • 当转换为布尔值时,
    0
    为false,但
    newnumber(0)
    为true,因此以下两个将具有不同的行为:
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
的构造函数会有自己的特定错误。