通常我们定义的构造函数需要new操作符实例调用构造函数,因为只有使用new的时候构造函数内用到的this对象会指向新创建的对象实例,如代码:
/**
* 作用域安全构造函数
* 琼台博客 www.qttc.net
*/
// 定义构造函数
function cus (name,age) {
this.name = name;
this.age = age;
}
var obj = new cus('琼台博客', 2);
console.log(obj.name); // Output: 琼台博客
console.log(obj.age); // Output: 2
因为使用new定义实例了cus构造函数,所以this对象指向新创建的obj对象。最后obj.name
与obj.age
分别都接受到构造函数赋予的值,结果可以正常弹出值。
但是,在没有使用new操作符来调用构造函数的情况下,情况就不一样了,我们都知道this默认指的是window,所以name与age都被赋予到window对象上。如代码:
/**
* 作用域安全构造函数
* 琼台博客 www.qttc.net
*/
// 定义构造函数
function cus(name,age){
this.name = name;
this.age = age;
}
// 没有使用new操作符构造函数
var obj = cus('琼台博客', 2);
console.log(obj.name); // Output: undefined
console.log(obj.age); // Output: undefined
console.log(window.name) // Output: 琼台博客
console.log(window.age) // Output: 2
这里原本是要把两个变量name与age赋予给obj变量的,但由于没有使用new操作符,所以直接赋予到window下了。结果导致obj.name与obj.age都是undefined,而window.name与window.age才可以正确弹出被赋予的值。
为了解决这个问题,我们可以先确认this对象是正确类型的实例,如果是就直接赋予值,如果不是就会创建一个实例并返回。
/**
* 作用域安全构造函数
* 琼台博客 www.qttc.net
*/
// 定义构造函数
function cus(name,age){
// 判断是不是使用new实例
if(this instanceof cus){
this.name = name;
this.age = age;
}else{
// 否则使用new实例并返回
return new cus(name,age);
}
}
// 没有使用new操作符构造函数
var obj = cus('琼台博客', 2);
console.log(obj.name); // Output: 琼台博客
console.log(obj.age); // Output: 2
这样,无论是否使用new操作符都能当作构造函数来使用了,不要难过担心被赋予到window对象下。