继承方式一:函数
function P1(){ this.name = "nn";
this.eat = function(){
console.log("I am eating!")
} } P1.prototype.say = function(){
console.log("say Hi!")
} function C1(){ this.type = "tt"; this.arr = [1,2,3];
P1.call(this) }
var c1 = new C1();
console.log(c1.name); // nn
console.log(c1.eat()); // I am eating!
console.log(c1.say()); //报错 Uncaught TypeError: c1.say is not a function
因而可知,这种方式下能够继承父类自身的的属性和方法,不能继承原型链上的属性和方法
继承方式二:this
function P2(){ this.name = "nn"; this.arr = [1,2,3]; this.eat = function(){ console.log("I am eating!"); } } P2.prototype.say = function(){ console.log("say Hi!"); } function C2(){ this.type = "tt"; } C2.prototype = new P2(); var c2 = new C2();
var c21 = new C2();
console.log(c2.name) // nn
console.log(c2.eat()) // I am eating!
console.log(c2.say()); // say Hi!
c2.arr.push(4);
console.log(c2.arr) // [1,2,3,4]
console.log(c21.arr); // [1,2,3,4]
因而可知,C2经过protopype把P2做为他的原型链,实现了继承,继承了P2的全部属性和方法,可是有一个问题就是对于引用的数据类型,一旦其中一个实例对引用类型改变,全部的实例化对象的引用类型值也改变了,就像是例子中的arr
继承方式三:spa
function P3(){ this.name = "nn"; this.arr = [1,2,3]; this.eat = function(){ console.log("I am eating!"); } } P3.prototype.say = function(){ console.log("say Hi!"); } function C3(){ this.type = "tt"; P3.call(this) } C3.prototype = new P3(); var c3 = new C3(); var c31 = new C3();
console.log(c3.name) // nn
console.log(c3.eat()) // I am eating!
console.log(c3.say()); // say Hi!
c3.arr.push(4);
console.log(c3.arr) // [1,2,3,4]
console.log(c31.arr); // [1,2,3]
为了解决2中出现的问题,利用了 P3.call(this) 这个方法,使得在每一个实例自己都有父亲的全部属性和方法,而不是去取原型链上的引用类型
继承方式四:prototype
function P4(){ this.name = "nn"; this.arr = [1,2,3]; this.eat = function(){ console.log("I am eating!"); } } P4.prototype.say = function(){ console.log("say Hi!"); } function C4(){ this.type = "tt"; P4.call(this) } C4.prototype = P4.prototype; var c4 = new C4(); var c41 = new C4();
这种方法看起来已经解决上面遇到的全部问题,
方式一的不能继承父元素的原型链上的方法,
方式二的修改原型链上引用类型会修改该全部实例的问题,
方法三的重复的实例化构造函数的问题,
可是其实方式二,三,四都还有一个问题,就是他们没法去判断谁是子元素的直接父元素,
instanceof只能判断构该构造函数的实例在这条原型链上,好比c4 instanceof P4 结果为true,c4 instanceof Object的结果也为 true
实际上 C4.prototype.constructor === P4 为 true
为了解决这个问题 能够参考方式五
继承方式五:code
function P5(){ this.name = "nn"; this.arr = [1,2,3]; this.eat = function(){ console.log("I am eating!"); } } P4.prototype.say = function(){ console.log("say Hi!"); } function C5(){ this.type = "tt"; P5.call(this) } C5.prototype = Object.create(P5.prototype); C5.prototype.constructor = C5
var c5 = new C5(); var c51 = new C5();
备注:使用Object.create()建立的js对象,没有constructor
好了,这就是对原型链以及继承的理解与实现,后续有新内容再继续补充!对象