JavaScript 构造函数可以充当构造器的角色,并且可以使用构造函数来创建新的对象.使用构造函数的好处是,能够通过预定义的属性和方法,创造尽可能多的对象。
我们先来看一个例子:
function newFunction(funcName) {
this.functionName = funcName;
this.outPutFunctionName = function () {
return "this is outPutFunctionName";
}
};
var fun = newFunction("funName");
if (fun&& fun.functionName) {
console.log("fun:"+fun.functionName);
}
if (fun && fun.outPutFunctionName) {
console.log("fun"+fun.outPutFunctionName);
}
if (window.functionName) {
console.log("window:"+window.functionName);
}
if (window.outPutFunctionName) {
console.log("window:"+window.outPutFunctionName());
}
如果稍加不留意思考,会得出如下的错误结果:
fun:funName
fun:this is outPutFunctionName
但是仔细想想在使用 var fun = newFunction("funName");
时,此时直接调用的是newFunction 这个函数,这个函数没有返回值,javascript默认返回undefined。所以fun的值为undefined。这样得到最终的输出结果为:
window:funName
window:this is outPutFunctionName
可是为什么window里面有对应的属性和方法名呢?因为函数是一个全局性质的特性,在定义函数时函数里面的this 就是指向window。所以window被追加了对应的属性和方法。这个可以通过this===window
来进行验证。
我们来看一下通过new的方式调用得到的结果:
function newFunction(funcName) {
this.functionName = funcName;
this.outPutFunctionName = function () {
return "this is outPutFunctionName";
}
};
var fun2 = new newFunction("funName2");
if (fun2 && fun2.functionName) {
console.log("fun:"+fun2.functionName);
}
if (fun2 && fun2.outPutFunctionName) {
console.log("fun:" + fun2.outPutFunctionName());
}
if (window.functionName) {
console.log("window:" + window.functionName);
}
if (window.outPutFunctionName) {
console.log("window:" + window.outPutFunctionName());
}
得到的结果为:
fun:funName2
fun:this is outPutFunctionName
通过直接调用和new 构造函数的区别可以看出来,直接调用构造函数是把里面对应的属性和方法直接添加到window对象上,而new 构造函数的形式则直接添加到对应的实例上面。这个细节还是必须注意的,如果都添加到window对象上,容易重名和被覆盖,而且js查找起来也比较慢些。那如何解决这个问题呢?可以判断this是不是函数的实例来判断.可以使用如下的类似形式,强制调用者使用构造函数的形式。
function newFunction(funcName) {
if(!(this instanceof newFunction)){
return new newFunction(funcName);
}
this.functionName = funcName;
this.outPutFunctionName = function () {
return "this is outPutFunctionName";
}
}