javascript
JavaScript对象继承方式
一、對(duì)象冒充
其原理如下:構(gòu)造函數(shù)使用 this 關(guān)鍵字給所有屬性和方法賦值(即采用類聲明的構(gòu)造函數(shù)方式)。因?yàn)闃?gòu)造函數(shù)只是一個(gè)函數(shù),所以可使 Parent 構(gòu)造函數(shù) 成為 Children 的方法,然后調(diào)用它。Children 就會(huì)收到 Parent 的構(gòu)造函數(shù)中定義的屬性和方法。例如,用下面的方式定義 Parent 和 Children:
]// 父類構(gòu)造函數(shù) var Parent = function(name){this.name = name;this.sayHi = function(){console.log("Hi! " + this.name + ".");}//前端全棧學(xué)習(xí)交流圈:866109386 };//面向1-3年前端人員 //幫助突破技術(shù)瓶頸,提升思維能力 // 子類構(gòu)造函數(shù) var Children = function(name){this.method = Parent;this.method(name); // 實(shí)現(xiàn)繼承的關(guān)鍵delete this.method;this.getName = function(){console.log(this.name);} };var p = new Parent("john"); var c = new Children("joe");p.sayHi(); // 輸出: Hi! john. c.sayHi(); // 輸出: Hi! joe. c.getName(); // 輸出: jo原理:就是把 Parent 構(gòu)造函數(shù)放到 Children 構(gòu)造函數(shù)里面執(zhí)行一次。那為什么不直接執(zhí)行,非要轉(zhuǎn)個(gè)彎把 Parent 賦值給 Children 的 method 屬性再執(zhí)行呢? 這跟 this 的指向有關(guān),在函數(shù)內(nèi) this 是指向 window 的。當(dāng)將 Parent 賦值給 Children 的 method 時(shí), this 就指向了 Children 類的實(shí)例。
二、原型鏈繼承
眾所周知,JavaScript 是一門基于原型的語(yǔ)言,在 JavaScript 中 prototype 對(duì)象的任何屬性和方法都被傳遞給那個(gè)類的所有實(shí)例。原型鏈利用這種功能來(lái)實(shí)現(xiàn)繼承機(jī)制:
// 父類構(gòu)造函數(shù) var Parent = function(){this.name = "john";this.sayHi = function(){console.log("Hi! " + this.name + ".");} };// 子類構(gòu)造函數(shù) var Children = function(){};Children.prototype = new Parent(); // 實(shí)現(xiàn)繼承的關(guān)鍵var p = new Parent(); var c = new Children();p.sayHi(); // 輸出: Hi! john. c.sayHi(); // 輸出: Hi! john.注意:調(diào)用 Parent 的構(gòu)造函數(shù),沒(méi)有給它傳遞參數(shù)。這在原型鏈中是標(biāo)準(zhǔn)做法。要確保構(gòu)造函數(shù)沒(méi)有任何參數(shù)。
三、使用 call 或 applay 方法
這個(gè)方法是與對(duì)象冒充方法最相似的方法,因?yàn)樗彩峭ㄟ^(guò)改變了 this 的指向而實(shí)現(xiàn)繼承:
// 父類構(gòu)造函數(shù) var Parent = function(name){this.name = name;this.sayHi = function(){console.log("Hi! " + this.name + ".");} };// 子類構(gòu)造函數(shù) var Children = function(name){Parent.call(this, name); // 實(shí)現(xiàn)繼承的關(guān)鍵this.getName = function(){console.log(this.name);} };var p = new Parent("john"); var c = new Children("joe");p.sayHi(); // 輸出: Hi! john. c.sayHi(); // 輸出: Hi! john. c.getName(); // 輸出: joeapply 方法本人就不舉列了,它和 call 方法的區(qū)別在于它的第二個(gè)參數(shù)必須是數(shù)組。
四、混合方式
對(duì)象冒充的主要問(wèn)題是必須使用構(gòu)造函數(shù)方式,這不是最好的選擇。不過(guò)如果使用原型鏈,就無(wú)法使用帶參數(shù)的構(gòu)造函數(shù)了。如何選擇呢?答案很簡(jiǎn)單,兩者都用。 在 JavaScript 中創(chuàng)建類的最好方式是用構(gòu)造函數(shù)定義屬性,用原型定義方法。這種方式同樣適用于繼承機(jī)制:
// 父類構(gòu)造函數(shù) var Parent = function(name){this.name = name; };Parent.prototype.sayHi = function(){console.log("Hi! " + this.name + "."); };// 子類構(gòu)造函數(shù) var Children = function(name, age){Parent.call(this, name); // 實(shí)現(xiàn)繼承的關(guān)鍵this.age = age; };Children.prototype = new Parent(); // 實(shí)現(xiàn)繼承的關(guān)鍵Children.prototype.getAge = function(){console.log(this.age); };//前端全棧開(kāi)發(fā)交流圈:866109386 //幫助1-3年前端人員突破技術(shù)瓶頸,提升思維 var p = new Parent("john"); var c = new Children("joe",30);p.sayHi(); // 輸出: Hi! john. c.sayHi(); // 輸出: Hi! joe. c.getAge(); // 輸出: 30五、使用Object.create 方法
Object.create 方法會(huì)使用指定的原型對(duì)象及其屬性去創(chuàng)建一個(gè)新的對(duì)象:
// 父類構(gòu)造函數(shù) var Parent = function(name){this.name = name; };Parent.prototype.sayHi = function(){console.log("Hi! " + this.name + "."); };// 子類構(gòu)造函數(shù) var Children = function(name, age){Parent.call(this, name); // 實(shí)現(xiàn)繼承的關(guān)鍵this.age = age; };Children.prototype = Object.create(Parent.prototype); // 實(shí)現(xiàn)繼承的關(guān)鍵 Children.prototype.constructor = children; // @Children.prototype.getAge = function(){console.log(this.age); };var p = new Parent("john"); var c = new Children("joe",30);p.sayHi(); // 輸出: Hi! john. c.sayHi(); // 輸出: Hi! joe. c.getAge(); // 輸出: 30@ 當(dāng)執(zhí)行 Children.prototype = Object.create(Parent.prototype) 這個(gè)語(yǔ)句后,Children 的 constructor 就被改變?yōu)?Parent ,因此需要將 Children.prototype.constructor 重 新指定為 Children 自身。
六、extends 關(guān)鍵字實(shí)現(xiàn)繼承
這個(gè)是 ES6 的語(yǔ)法糖,下面看下es6實(shí)現(xiàn)繼承的方法:
class Parent {constructor(name, age) {this.name = name;this.age = age;} }class Children extends Parent {constructor(name, age, job) {this.job = job; // 這里會(huì)報(bào)錯(cuò)super(name, age);this.job = job; // 正確} }上面代碼中,子類的constructor方法沒(méi)有調(diào)用super之前,就使用this關(guān)鍵字,結(jié)果報(bào)錯(cuò),而放在super方法之后就是正確的。子類Children的構(gòu)造函數(shù)之中的super(),代表調(diào)用父類Parent的構(gòu)造函數(shù)。這是必須的,否則 JavaScript 引擎會(huì)報(bào)錯(cuò)。
注意,super雖然代表了父類Parent的構(gòu)造函數(shù),但是返回的是子類Children的實(shí)例,即super內(nèi)部的this指的是Children,因此super()在這里相當(dāng)于Parent.prototype.constructor.call(this)。
原文鏈接:https://my.oschina.net/u/3970421/blog/2872629
轉(zhuǎn)載于:https://www.cnblogs.com/lovellll/p/10245931.html
總結(jié)
以上是生活随笔為你收集整理的JavaScript对象继承方式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 记那一次-----环环相抱何是了?
- 下一篇: gradle idea java ssm