JS继承的实现方式
原型鏈繼承:
//原型鏈繼承:把父類的私有+公有的屬性和方法,都作為子類公有的屬性;//核心:不是把父類私有+公有的屬性克隆一份一模一樣的給子類的公有吧;他是通過__proto__建立和子類之間的原型鏈,當子類的實例需要使用父類的屬性和方法的時候,可以通過__proto__一級級找上去使用;function F(){//父類;this.x=100;this.y=300;}F.prototype.showX=function(){alert(123);};function S(){//子類;this.y=200;}S.prototype=new F;//子類公有方法上繼承父類私有+公有的屬性S.prototype.constructor=S;//添加子類constructor指向var p1=new S;var p2=new S;console.dir(p1)/** 私有屬性:y:200* __proto__:* constructor:S;* x:100;* __proto__:* constructor:F;* showX:function(){}*** *///p1.__proto__.__proto__.showX();//跳過了私有屬性的查找,直接到公有屬性上去找//p1.showX();//會根據原型鏈一級級的往上查找;//S.prototype.__proto__.showX()//F.prototype.showX();//alert(p1.y)p1.__proto__.__proto__.showX=function(){alert('456789')}p1.showX();p2.showX();
?
call繼承:
//call繼承:把父類私有的屬性和方法繼承給了子類私有的屬性和方法; function F(){this.x=100;this.y=200;}var f1=new F;console.dir(f1)function S(){F.call(this)this.z=300;}var p1=new S;console.dir(p1)//私有屬性:x:100; y:200
?
冒充繼承://冒充繼承:把父類私有+公有的屬性和方法,克隆(for in循環)了一份一模一樣的給子類私有的屬性和方法;function F(){//父類; 父類私有的屬性和方法this.x=100;this.y=300;}F.prototype.showX=function(){//父類共有的屬性和方法;alert(123);};function S(){var tmp=new F;console.dir(tmp)for(var attr in tmp){this[attr]=tmp[attr];}};var p1=new S;console.dir(p1)
?
混合繼承:call繼承+原型鏈繼承/** call繼承:把父類私有的屬性和方法,都給了子類私有的屬性和方法---call;* 原型鏈繼承:把父類私有+公有的屬性和方法,都給了子類公有的屬性和方法* 問題:父類私有的給了子類私有,也給了子類公有* */function F(){this.x=100;}F.prototype.showX=function(){};function S(){F.call(this);//完成了call繼承 };S.prototype=new F;//完成了原型鏈繼承;var p1=new S;console.dir(p1);/** 私有屬性:x:100;* __proto__:* x:100;* __proto__:* constructor:F,* showX:function...* */混合繼承:call繼承+拷貝繼承
//混合繼承:call繼承+拷貝繼承 function extend(newEle,oldEle){for(var attr in oldEle){newEle[attr]=oldEle[attr];} } function F(){this.x=100;this.showX=function(){} } F.prototype.getX=function(){}; F.prototype.getX1=function(){}; var f1=new F; console.dir(f1) function S(){F.call(this)//call繼承 } extend(S.prototype, F.prototype);//拷貝繼承 S.prototype.cc=function(){ } var p1=new S; console.dir(p1);
?
寄生式組合: call繼承+Object.create();//寄生式組合: call繼承+Object.create(); function F(){this.x=100; } F.prototype.showX=function(){}; function S(){F.call(this)//只繼承了私有的; }function Tmp(){}; Tmp.prototype= F.prototype;//只把父級公有的屬性和方法過渡到了一個空類的原型上; S.prototype=new Tmp; S.prototype.constructor=S;var p1=new S; console.dir(p1)
?
for in拷貝
var obj={name:'zhufeng',age:8}; var obj2={} function extend(newEle,oldEle){for(var attr in obj){obj2[attr]=obj[attr];} }
?
//for in循環在遍歷時,默認會把自己的私有和它所屬原型上擴展的屬性和方法都遍歷到 //obj.propertyIsEnumerable() 、 obj.hasOwnProperty()判斷是否私有屬性 Object.prototype.aaa=function(){} var obj={name:'小明',age:8 } console.log(obj)//obj.__proto__ 上有aaa(){} for(var key in obj){// if(obj.propertyIsEnumerable(key)){if(obj.hasOwnProperty(key)){console.log(key) //name age } }
?
?其它:
關于Object.create()
Object.prototype.aaa=function(){} var obj={name:'小明',age:8 } var obj2=Object.create(obj) //創建一個新對象,把新對象obj作為這個對象的原型 console.log(obj2)//封裝Object.create() function object(o){function Fn(){}Fn.prototype=oreturn new Fn; } var newObj=object(obj)
?
轉載于:https://www.cnblogs.com/sayidf/p/9250629.html
總結
- 上一篇: 02Lua入门
- 下一篇: LeetCode-198. 打家劫舍