1,借助 call / apple;
写法
function Fn(){
this.type = "dog"
this.say = function(){
console.log("wan")
}
}
function Fnn(name){
Fn.call(this); // 让Fn在这里执行一次,因为改变了Fn 的执行环境,所以 type等属性 被挂在了 当前this 的实例上;
this.name = name;
this.sayName = function(){
console.log(this.name)
};
}
缺点
只是部分继承了 Fn; 如果Fn 的原型上的方法改变了,Fnn 实例是拿不到的;
2,将父类的实例 作为 子类的原型;(类是一个构造函数)
写法
function Fn(){
this.type = "dog"
this.say = function(){
console.log("wan")
}
}
function Fnn(name){
this.name = name;
this.sayName = function(){
console.log(this.name)
};
}
//这时 Fnn.prototype.constructor === new Fnn().constructor; // 原型的 constructor 等于 实例的 constructor;
Fnn.prototype = new Fn();//让 父类的实例 作为 子类的 原型,父类的原型改变了属性,由于父类的实例也能拿到,所以,Fn的实例也能拿到。
Fnn.prototype.constructor = Fnn;// 因为改变Fnn 的原型以后,Fnn的原型的constructor指向的其实已经是Fn实例的constructor了,也就是Fn,这是我们不希望的;手动让它指向自己的构造函数;
缺点
由于 所有 Fnn 都是共享 Fn 实例 作为原型,所以,一旦改变某个实例的 原型方法,所有 实例都改变了。
var a = new Fnn();
var b = new Fnn();
console.log(a.type,b.type) // dog dog
a.type = "gou";
console.log(b.type)//gou
3,组合1+2方式
写法
function Fn(){
this.type = "dog"
this.say = function(){
console.log("wan")
}
}
function Fnn(name){
Fn.call(this); // 继承实例方法
this.name = name;
this.sayName = function(){
console.log(this.name)
};
}
//Fnn.prototype = new Fn(); // 继承原型方法
Fnn.prototype = Fn.prototype;// 推荐这样写
缺点
new Fnn.constructor 指向了 Fn ;
无法用 instransof 判断原型;
4 通过Object.create();
写法
function Fn(){
this.type = "dog"
this.say = function(){
console.log("wan")
}
}
function Fnn(name){
Fn.call(this); // 继承实例方法
this.name = name;
this.sayName = function(){
console.log(this.name)
};
}
Fnn.prototype = Objcet.create(Fn.prototype) //create 返回一个新对象,新对象的原型是 Fn.prototype
Fnn.prototype.constructor = Fnn;
// Fnn 的实例会访问到 新对象,新对象 访问到 Person 原型,所以继承了 Fn。同时改变Fnn 的原型不会 影响 Fn 的其它 子类;
原文链接:https://www.f2er.com/note/411448.html