下你所需,载你所想!
IT技术源码资料下载网站

深入理解自定义构造函数javascript模式笔记

:其他软件 2020-09-07 11:05:39

深入理解自定义构造函数javascript模式笔记

深入理解自定义构造函数
在javascript中,有很多方法可以创建对象
通过字面量的方式
通过内置的构造函数
通过自定义的构造函数
举个例子 : 这是一个最常见的自定义构造函数,实例化一个Person对象叫tianqin
var Person = function(name){
this.name = name;
this.say = function(){
return "I am" + " "+this.name
};
};

var tianQin = new Person("tianqin");
tianQin.say();
输出结果
但是在使用 new 这个操作符的时候,函数内部发生了一系列隐式的行为
创建一个空对象并且this变量引用了这个对象,同时继承了该对象的原型
属性和方法被加入到this引用的对象中去
新创建的对象用this所引用,并且最后隐式的返回this
伪代码表示这个过程
var Person = function(){
var this = {
//隐式的创建了一个this对象
}
this.name = name;
this.say = function(){
return "I am" + " "+this.name
};//这个过程其实是在给隐式创建的this对象添加属性和方法
return this;// 这里最后隐式的返回this(如果没有显示的返回其他对象,换句话说可以返回其他显示的对象)
}
我们所看到的创建的一个空对象this,其实并不是空的,他已经从原型中继承了很多属性
其实是 var this = Object.create( Person.prototype )
值得注意的是:这里将say方法添加到了this中,这样做会导致在任何情况下调用的时候调用new Person()的时候都会在内存中创建一个新的函数,这种方法的效率是非常低下的
更好的方法是将方法添加到Person类的原型中
Person.prototype.say = function() {
return "I am" + " " + this.name
};
现在我们手动改变一下这个隐式的过程, 手动加上了一个自定义的对象
var Obj = function(){
this.name = "tianQin";
var myobj = {
//就像隐式的生成this对象一样,这里手动的添加了一个新的自定义对象
}
myobj.name = "hlh";
return myobj;
//给新的对象添加了属性,最后返回这个新的对象
}
var obj = new Obj();
console.log(obj.name);
看结果:输出了hlh
所以可以发现可以在构造函数中自由的返回任何对象
但是有没有想过一个问题,就是我们在实例化对象的时候,为什么要用new呢?
如果没有new会怎么样?
其实,没有new并不会导致语法错误,但可能会导致逻辑错误和意外行为的发生,可能会导致构造函数中的this指向了全局对象window。
举个例子:
var Msg = function(){
this.msg = "这是构造函数"
}
var newMsg = new Msg(); //这是使用了 new 的方式

console.log(newMsg.msg);
console.log(typeof newMsg);
var newMsg2 = Msg(); //这是不使用 new 的方式
// console.log(newMsg2.msg); 报错

console.log(window.msg);
console.log(typeof newMsg2);
我们来看一下输出结果:
从上至下依次是:
这种意外在ECMAscript5中得到了解决,并且在严格模式中,this不会指向全局变量
还有一种巧妙的办法叫做叫做使用一个命名公约这个命名可以是that 也可以是其他的
使用that改造上述代码:
var Msg = function(){
var that = {};
that.msg = "这是构造函数"
return that;
}
var newMsg = new Msg(); //这是使用了 new 的方式
console.log(newMsg.msg);
console.log(typeof newMsg);
var newMsg2 = Msg(); //这是不使用 new 的方式
console.log(newMsg2.msg);

console.log(window.msg);
console.log(typeof newMsg2);
再来看一下输出:
发现使用new 和不使用 new这里都可以实例化一个对象