1. Always remember to use the New keyword to execute the constructor.
As mentioned earlier, you can use constructors to create JavaScript objects that use the New keyword when used, but what if you forget to write the new keyword? In fact, this function will still be executed, there is no syntax error, but there is a logic error . Therefore, if the new keyword is not used, the this pointer in the function will not be stored as a reference to the object and is actually stored as a global object . If you execute the code on the page, this is the window. For example, at this time, the This.member in the constructor is pointing to Window.member. If the member attribute is not defined in the Global Object window, this property will be implicitly declared! This could make a big mess:
Constructorfunction Waffle () { this.tastes = "Yummy";} A new Objectvar good_morning = new Waffle (); Console.log (typeof good_morning); "Object" Console.log (good_morning.tastes); "Yummy"//antipattern://forgotten ' new ' var good_morning = waffle (); Console.log (typeof good_morning); "Undefined" console.log (window.tastes); "Yummy"
This is why we should capitalize the first letter of the constructor, so that one can see that it is a constructor. Because it will be problematic if it is not executed with the new keyword.
2. Do not use this in the constructor, with that
Since this is a hidden hazard in the constructor, we can use this instead of that. Of course, that's not a keyword. So the constructor will look like this:
Function waffle () { var that = {}; That.tastes = "Yummy"; return that;}
This may seem a bit odd, but it does improve the security of your code. If you need to construct an object that is simple enough, you can return a literal object directly:
Function waffle () { return { tastes: "Yummy" };}
Using the constructor written in this way, you can always return an object that we need, whether it is called:
var first = new Waffle (), second = waffle (); Console.log (first.tastes);//"Yummy" Console.log (second.tastes);//" Yummy
The biggest problem with this pattern is that the relationship between the new object and the prototype of the Waffle object is lost, and adding a generic method through Waffle's prototype will not work. If you want to guarantee the relationship between the new object and the Waffle prototype, you can use instanceof to make a judgment and then decide how to create the object:
Function waffle () { if (!) ( This instanceof waffle) { return new waffle (); } This.tastes = "Yummy";} Waffle.prototype.wantAnother = true;//testing Invocationsvar first = new Waffle (), second = waffle (); Console.log ( First.tastes); "Yummy" Console.log (second.tastes); "Yummy" Console.log (First.wantanother); Trueconsole.log (Second.wantanother); True
There is also a common way to check the way the constructor is called, which is judged by Arguments.callee:
if (! ( This instanceof Arguments.callee) { return new Arguments.callee ();}
The principle of this approach is that all function objects have a arguments member object, and one of the arguments properties is called callee, which points to the caller of the function. However, this approach does not apply to strict JavaScript standards, so it is not recommended.
JavaScript basics about constructors, the new keyword, and the This keyword (009)