标签:
Js所有的函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称原型。这个函数包括构造函数和普通函数,我们讲的更多是构造函数的原型,但是也不能否定普通函数也有原型。譬如普通函数:
function A(x){ this.x=x; } var obj=new A(1);
实例化obj对象有三步:
function A(x){ this.x=x; this.say = function(){alert(‘hi‘)} ; }
另一种:
A.prototype.say=function(){alert("Hi")};
区别:
前者的话,每一个对象都有关于say方法的一个副本。
后者,这个原型对象的say方法是唯一的副本给大家共享的。(这是通过内部的_proto_链来实现的。)
简单的继承实现。(js没有类,这里只是指构造函数)
function A(x){ this.x=x; } function B(x2,y){ this.tmpObj=A; this.tmpObj(x2); delete this.tmpObj; this.y=y; }
5、6、7行:(临时工角色)
创建临时属性tmpObj引用构造函数A,然后在B内部执行,执行完后删除。
B当然就拥有了x属性:
function A(x){ this.x=x; } function B(x2,y){ this.x=x2; this.y=y; }
当然B的x属性和A的x属性两者是独立,所以并不能算严格的继承。
第5、6、7行有更简单的实现:
A.call(this,x);
B虽然继承了A构造对象的所有属性方法,但是不能继承A的原型对象的成员。
function A(x){ this.x=x; } A.prototype.a = "a"; function B(x2,y){ A.call(this, x); this.y=y; }
这样子B里面是没有继承 A.prototype.a = "a"; 属性的!
解决上面的问题:
function A(x){ this.x = x; } A.prototype.a = "a"; function B(x2,y){ this.y = y; A.call(this,x2); } B.prototype.b1 = function(){ alert("b1"); } B.prototype = new A(); //注意A里面没有带参数! // B先是被“类继承”一次,又被“原型继承”一次 //故B里面有两个x属性,一个为"a",一个undefined! //这时,"原型属性x"要让位于"实例对象属性x",还是"a"了。 // 还要注意:此时,B.prototype.constructor就是构造对象A了! //alert(B.prototype.constructor)出来后就是"function A(x){...}" 下面有解决的 //设置了原型方法b1,但是上面一行,原型指向改变,原来具有b1的原型对象被抛弃,自然又没有b1了 //再来个b2 B.prototype.b2 = function(){ alert("b2"); } B.prototype.constructor = B; // 将B原型的构造器重新指向了B构造函数 // 实例化B一个 var obj = new B(1,3);
类继承是这行:A.call(this.x);
原型继承是这行:B.prototype = new A();
如果没有
B.prototype.constructor = B;
那是不是obj = new B(1,3)会去调用A构造函数实例化呢?
答案是否定的:
你会发现obj.y=3,所以仍然是调用的B构造函数实例化的。
只是
obj.constructor===A //true
对于new B()的行为来说,执行了上面所说的通过构造函数创建实例对象的3个步骤:
原文出处:http://ljchow.cnblogs.com
标签:
原文地址:http://www.cnblogs.com/gallenhu/p/4511926.html