在多个程序员开发一个页面的时候,作用域安全的构造函数就很有用了,我们不能保证每个人写的代码都那么小心,如果一个人代码出错,影响到全局属性,那么这种错误难以追踪调试,这时候使用作用域安全的构造函数就可以避免此类问题。
属性值被挂载到window
JavaScript中构造函数其实是一个使用new操作符调用的函数,在调用时, 构造函数内部用到的this对象会指向新创建的对象
function Person( name, age ){
this.name = name;
this.age = age;
}
var person = new Person( 'Caleb', 20 );
使用new操作符时,会创建一个新的Person对象,并给它分配属性。正常使用new操作符不会出现问题。问题出在疏忽忘记使用new操作符来调用构造函数的情况下 - 由于this对象是在运行期绑定的所以直接调用Person(),this会映射到全局对象window上,导致错误对象属性的意外增加。
var person = Person( 'Caleb', 20 );
alert( window.name ); //Caleb
alert( window.age ); //20
这样原本针对Person对象的属性被添加window对象,因为构造函数没有通过new操作符调用,而是作为普通函数被调用的,由于this的晚绑定而被解析成window对象。
window的那么属性是用来标识链接目标和框架的,这里对该属性的偶然覆盖可能会导致页面上的其它错误,这个问题的解决方法就是创建一个作用域安全的构造函数。
作用域安全的构造函数
作用域安全的构造函数在进行属性赋值之前会this对象是否是正确类型的实例,如果不是那么创建新的实例并返回,改造一下上面的构造函数。
function Person( name, age ){
if(this instanceof Person){
this.name = name;
this.age = age;
}else{
return new Person( name, age );
}
}
var person = Person( 'Caleb', 20 );
alert( window.name ); //""
alert( person.name ); //Caleb
这段代码中构造函数添加了一个检查,确保this对象是Person的实例,如果不是则使用new操作符调用,如果是则在实例内添加属性。
这样保证了无论是否显示使用new操作符,都可以正确构造对象。貌似完美了,但是仍旧有问题。
网友评论