Why to avoid creating objects of primitives in JavaScript?

前端 未结 2 1834
独厮守ぢ
独厮守ぢ 2020-12-05 01:40

I am following a JavaScript tutorial on W3Schools. While reading almost on each page they give note to user to \"Avoid creating objects\" and to use primitive data types ins

2条回答
  •  有刺的猬
    2020-12-05 02:31

    It changes the intuitive way the operators behave with numbers, strings and booleans:

    • the strict comparison (===) breaks when any of the numbers is constructed, so 42 === 42 is true, while 42 === new Number(42) is not,
    • the abstract comparison (==) breaks when both numbers are objects, so 42 == new Number(42) is true, while new Number(42) == new Number(42) is not,
    • the typeof operator gives different result when a number is constructed, so typeof(42) is number, but typeof(new Number(42)) is object,
    • when converted to a boolean, 0 is false, but new Number(0) is true, so the following two will have different behavior:

    var a = 0;
    if (a)
      console.log("not zero");
    else
      console.log("zero!");     // "zero!"
    
    var b = new Number(0);
    if (b)
      console.log("not zero");     // "not zero"
    else
      console.log("zero!");

    So, avoid new Number, new String and new Boolean.

    Apart from that, there is the issue of using / not using new with constructors. It stems from several facts:

    • in JS, a constructor is a regular function, using this.foo syntax to add new properties and methods;
    • when invoked without the new keyword, this becomes the global object, leading to side effects.

    As a result, a tiny mistake can have catastrophic effects:

    color = "blue";
    
    var Fruit = function(color) {
      this.color = color;
      return this;
    };
    
    var apple = new Fruit("green");
    
    console.log(apple.color);       // "green"  --  okay
    
    console.log(color);             // "blue"  --  okay
    
    var banana = Fruit("yellow");
    
    console.log(banana.color);      // "yellow"  --  okay
    
    console.log(color);             // "yellow"  --  wait, what?
    
    console.log(banana.apple);      // "{ color: 'green' }"  --  what??
    
    console.log(banana.document);   // "{ location: [Getter/Setter] }"  --  what???

    (That's why some people resort to adding explicit checks in the constructor, or using closures instead. But that's for another story.)

提交回复
热议问题