JS虽然不像是JAVA那种强类型的语言,但也有着与JAVA类型的继承属性,那么JS中的继承是如何实现的呢?
一、构造函数继承
函数中,同样属于两个新创建的函数,也是不相等的
function Fn(name){
this.name = name;
this.show = function(){
alert(this.name);
}
}
var obj1 = new Fn("AAA");
var obj2 = new Fn("BBB");
console.log(obj1.show==obj2.show); //false
此时可以看出构造函数的多次创建会产生多个相同函数,造成冗余太多。
利用原型prototype解决。首先观察prototype是什么东西
function Fn(){}
console.log(Fn.prototype);
//constructor表示当前的函数属于谁
//__proto__ == [[prototype]],书面用语,表示原型指针
var fn1 = new Fn();
var fn2 = new Fn();
Fn.prototype.show = function(){
alert(1);
}
console.log(fn1.show==fn2.show); //ture
此时,任何一个对象的原型上都有了show方法,由此得出,构造函数Fn.prototype身上的添加的方法,相当于添加到了所有的Fn身上。
二、call和applay继承
函数Son的实例化对象
//将Father里面的this改变成指向Son的实例化对象,当相遇将father里面所有的属性和方法都复制到了son身上
//Father.call(this,abc);//继承结束,call适合固定参数的继承
//Father.apply(this,arguments);//继承结束,apply适合不定参数的继承
}
father.show()
var son = new Son("一般木匠");
son.show();
三、原型链继承(demo)
这个的么实现一个一个简单的拖拽,a->b的一个继承。把a的功能继承给b。
HTML:
CSS:
JS:
this.cliW-this.ele.offsetWidth?this.x=this.cliW-this.ele.offsetWidth:this.x;
this.y=this.y>this.cliH-this.ele.offsetHeight?this.y=this.cliH-this.ele.offsetHeight:this.y;
this.ele.style.left=this.x+'px';
this.ele.style.top=this.y+'px';
}
}
new Drag().init('drag1')
function ChidrenDrag(){}
ChidrenDrag.prototype=new Drag()
new ChidrenDrag().init('drag2')
四、混合继承
方法
//但这是一种错误的原型继承示例,如果使用这种方式,会导致修改son原型上的show方法时,会把father身上的show也修改
//内存的堆和栈机制
Son.prototype.show = function(){
alert("我是son,这是我的技能"+this.skill);
}
var father = new Father("专家级铁匠","father");
var son = new Son("熟练级铁匠","son");
father.show();
son.show();
上面的示例应该修改成以下形式:
以上红色的代码应改成:
for(var i in Father.prototype){
Son.prototype[i] = Father.prototype[i];
}
//遍历father的原型身上的所有方法,依次拷贝给son的原型,这种方式称为深拷贝
这种继承方式叫做混合继承,用到了for-in继承,cell和apple继承。
五、Es6的class继承(demo)
这个demo的功能和原型链继承的demo功能一样,a->b的继承
HTML: