JS中的原型与继承
原型:
Js所有的函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称原型。这个函数包括构造函数和普通函数,我们讲的更多是构造函数的原型,但是也不能否定普通函数也有原型。譬如普通函数:
;
}
alert(F.prototype instanceof Object) //true
构造函数实例化对象的过程。
function A(x){ this.x=x; } var obj=new A(1);
实例化obj对象有三步:
- 1. 创建obj对象:var obj=new A(1);
- 2. 将obj的内部__proto__指向构造他的函数A的prototype. 类的实例对象的constructor属性永远指向"构造函数"的prototype.constructor. obj是没有prototype属性的,但是有内部的__proto__,通过__proto__来取得原型链上的原型属性和原型方法
- 3. 将obj作为this去调用构造函数A,从而设置成员(即对象属性和对象方法)并初始化。 (obj作为了this, 故 obj.x = x)
2种方式定义原型方法:
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个步骤:
- 第一步,创建空对象;
- 第二步,obj.__proto__ === B.prototype; (B.prototype是具有x,a,b2成员的。然后obj.constructor指向了B.prototype.constructor,即构造函数A;)
- 第三步,调用的构造函数B去设置和初始化成员,具有了属性x,y。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。