乐趣区

JavaScript中的继承及实现代码

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
// 前端全栈学习交流圈:866109386
// 面向 1 - 3 经验年前端开发人员
// 帮助突破技术瓶颈,提升思维能力
此时,任何一个对象的原型上都有了 show 方法,由此得出,构造函数 Fn.prototype 身上的添加的方法,相当于添加到了所有的 Fn 身上。
二、call 和 applay 继承
function Father(skill){
this.skill = skill;
this.show = function(){
alert(“ 我会 ”+this.skill);
}
}
var father = new Father(“ 绝世木匠 ”);
function Son(abc){
// 这里的 this 指向函数 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:
<div id=”drag1″></div>
<div id=”drag2″></div>
CSS:
*{margin: 0;padding: 0;}
#drag1{width: 100px;height: 100px;background: red;position: absolute;}
#drag2{width: 100px;height: 100px;background: black;position: absolute;left: 500px;}
JS:
function Drag(){}
Drag.prototype={
constructor:Drag,
init:function(id){
this.ele=document.getElementById(id);
this.cliW=document.documentElement.clientWidth||document.body.clientWidth;
this.cliH=document.documentElement.clientHeight||document.body.clientHeight;
var that=this;
this.ele.onmousedown=function(e){
var e=event||window.event;
that.disX=e.offsetX;
that.disY=e.offsetY;
document.onmousemove=function(e){
var e=event||window.event;
that.move(e);
}
that.ele.onmouseup=function(){
document.onmousemove=null;
}
}
},
move:function(e){
this.x=e.clientX-this.disX;
this.y=e.clientY-this.disY;
this.x=this.x<0?this.x=0:this.x;
this.y=this.y<0?this.y=0:this.y;
this.x=this.x>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’)
// 前端全栈学习交流圈:866109386
// 面向 1 - 3 经验年前端开发人员
// 帮助突破技术瓶颈,提升思维能力
四、混合继承
function Father(skill,id){
this.skill = skill;
this.id = id;
}
Father.prototype.show = function(){
alert(“ 我是 father, 这是我的技能 ”+this.skill);
}
function Son(){
Father.apply(this,arguments);
}
// 如果不做 son 的原型即成 father 的原型,此时会报错:son.show is not a function
Son.prototype = Father.prototype;
// 因为,如果不让 son 的原型等于 father 的原型,son 使用 apply 是继承不到原型上的方法
// 但这是一种错误的原型继承示例,如果使用这种方式,会导致修改 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:
<div id=”drag1″></div>
<div id=”drag2″></div>
CSS:
*{margin: 0;padding: 0;}
#drag1{width: 100px;height: 100px;background: red;position: absolute;}
#drag2{width: 100px;height: 100px;background: black;position: absolute;left: 500px;}
JS:
class Drag{
constructor(id){
this.ele=document.getElementById(id);
this.init();
};
init(){
var that=this;
this.ele.onmousedown=function(e){
var e=event||window.event;
that.disX=e.offsetX;
that.disY=e.offsetY;
document.onmousemove=function(e){
var e=event||window.event;
that.move(e);
}
that.ele.onmouseup=function(){
document.onmousemove=null;
that.ele.onmouseup=null;
}// 前端全栈学习交流圈:866109386
}// 面向 1 - 3 经验年前端开发人员
};// 帮助突破技术瓶颈,提升思维能力
move(e){
this.ele.style.left=e.clientX-this.disX+”px”;
this.ele.style.top=e.clientY-this.disY+”px”;
}
}
new Drag(“drag1”);
class ExtendsDrag extends Drag{
constructor(id){
super(id);
}
}
new ExtendsDrag(“drag2”)

退出移动版