Why avoid creating objects in JavaScript?

I follow the JavaScript guide to W3Schools. When reading on almost every page, they give a note to the user “Avoid creating objects” and use primitive data types instead. They provide a basis for this, because "the code becomes difficult to understand or the execution speed will be reduced if the object is used." Is it true that we should avoid creating objects in JavaScript?

For example:

var value = new Number(1); // Avoid this var value = 1; // do something like this instead. 
+49
javascript
Jan 04 '17 at 7:01
source share
2 answers

The statement "avoid creating objects" in itself is absurd in JavaScript, which has objects everywhere and is one of the most object-oriented languages. But "avoid creating object versions of primitives," which is the code you specify, really. That is, avoid new String , new Number and new Boolean .

JavaScript has both primitive and object versions of strings, numbers, and Booleans. There was almost never a reason to create an object version of any of them explicitly, and this can lead to confusion; see inline comments:

 var s1, s2, n1, n2; // These are false because with ===, an object is never equal to a non-object s1 = new String("hi"); s2 = "hi"; console.log(s1 === s2); // false n1 = new Number(42); n2 = 42; console.log(n1 === n2); // also false // These are false because even with ==, two *different* objects are never equal // (even if they're equivalent) s1 = new String("what the..."); s2 = new String("what the..."); console.log(s1 == s2); // also false n1 = new Number(42); n2 = new Number(42); console.log(n1 == n2); // also false 

Object versions of strings, numbers, and booleans basically exist to allow primitives to be provided to methods using the same mechanism that provides methods for object types. When you do

 console.log("foo".toUpperCase()); // "FOO" 

a temporary object is created for the primitive string "foo" , and then the toUpperCase property is read from this object. Since the object inherits from String.prototype , it has toUpperCase , and all is well. When the operation is completed, the temporary object is discarded (unless something refers to it, but does nothing and cannot do anything with toUpperCase , you need to add the String.prototype method, which returns the object in order to be held).

+104
Jan 04 '17 at 7:16
source share

This changes the intuitive way that operators behave with numbers, strings, and builers:

  • strict comparison ( === ) breaks when building any of the numbers, so 42 === 42 true, and 42 === new Number(42) is not,
  • abstract comparison ( == ) breaks when both numbers are objects, so 42 == new Number(42) true, and new Number(42) == new Number(42) is not,
  • the typeof operator gives a different result when building the number, so typeof(42) number , but typeof(new Number(42)) is object ,
  • when converting 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 .

In addition, there is the problem of using / not using new with constructors. This is due to several facts:

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

As a result, a tiny mistake can have disastrous consequences:

 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??? 

(This is why some people resort to adding explicit checks to the constructor or use closure instead. But this is for a different story.)

+11
Jan 04 '17 at 18:25
source share



All Articles