摘要:使用關(guān)鍵字熟悉的同學(xué)應(yīng)該非常熟悉這個(gè)關(guān)鍵字,中的繼承都是靠它實(shí)現(xiàn)的。新加入的關(guān)鍵字是語法糖,本質(zhì)還是函數(shù)使用修改之前的例子,將會(huì)更簡(jiǎn)單在下面的例子,定義了一個(gè)名為的類,然后定義了一個(gè)繼承于的類。
使用Object.create實(shí)現(xiàn)類式繼承
下面是官網(wǎng)的一個(gè)例子
//Shape - superclass function Shape() { this.x = 0; this.y = 0; } Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info("Shape moved."); }; // Rectangle - subclass function Rectangle() { Shape.call(this); //call super constructor. } Rectangle.prototype = Object.create(Shape.prototype); var rect = new Rectangle(); rect instanceof Rectangle //true. rect instanceof Shape //true. rect.move(1, 1); //Outputs, "Shape moved."
此時(shí)Rectangle原型的constructor指向父類,如需要使用自身的構(gòu)造,手動(dòng)指定即可,如下
Rectangle.prototype.constructor = Rectangle;使用utilities工具包自帶的util.inherites
語法
util.inherits(constructor, superConstructor)
例子
const util = require("util"); const EventEmitter = require("events"); function MyStream() { EventEmitter.call(this); } util.inherits(MyStream, EventEmitter); MyStream.prototype.write = function(data) { this.emit("data", data); } var stream = new MyStream(); console.log(stream instanceof EventEmitter); // true console.log(MyStream.super_ === EventEmitter); // true stream.on("data", (data) => { console.log(`Received data: "${data}"`); }) stream.write("It works!"); // Received data: "It works!"
也很簡(jiǎn)單的例子,其實(shí)源碼用了ES6的新特性,我們瞅一瞅
exports.inherits = function(ctor, superCtor) { if (ctor === undefined || ctor === null) throw new TypeError("The constructor to "inherits" must not be " + "null or undefined"); if (superCtor === undefined || superCtor === null) throw new TypeError("The super constructor to "inherits" must not " + "be null or undefined"); if (superCtor.prototype === undefined) throw new TypeError("The super constructor to "inherits" must " + "have a prototype"); ctor.super_ = superCtor; Object.setPrototypeOf(ctor.prototype, superCtor.prototype); };
其中Object.setPrototypeOf即為ES6新特性,將一個(gè)指定的對(duì)象的原型設(shè)置為另一個(gè)對(duì)象或者null
語法
Object.setPrototypeOf(obj, prototype)
obj為將要被設(shè)置原型的一個(gè)對(duì)象
prototype為obj新的原型(可以是一個(gè)對(duì)象或者null).
如果設(shè)置成null,即為如下示例
Object.setPrototypeOf({}, null);
感覺setPrototypeOf真是人如其名啊,專門搞prototype來玩。
那么這個(gè)玩意又是如何實(shí)現(xiàn)的呢?此時(shí)需要借助宗師__proto__
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) { obj.__proto__ = proto; return obj; }
即把proto賦給obj.__proto__就好了。
使用extends關(guān)鍵字熟悉java的同學(xué)應(yīng)該非常熟悉這個(gè)關(guān)鍵字,java中的繼承都是靠它實(shí)現(xiàn)的。
ES6新加入的class關(guān)鍵字是語法糖,本質(zhì)還是函數(shù).
使用extends修改之前util.inherits的例子,將會(huì)更簡(jiǎn)單
const EventEmitter = require("events"); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on("event", function() { console.log("an event occurred!"); }); myEmitter.emit("event");
在下面的例子,定義了一個(gè)名為Polygon的類,然后定義了一個(gè)繼承于Polygon的類 Square。注意到在構(gòu)造器使用的 super(),supper()只能在構(gòu)造器中使用,super函數(shù)一定要在this可以使用之前調(diào)用。
class Polygon { constructor(height, width) { this.name = "Polygon"; this.height = height; this.width = width; } } class Square extends Polygon { constructor(length) { super(length, length); this.name = "Square"; } }
使用關(guān)鍵字后就不用婆婆媽媽各種設(shè)置原型了,關(guān)鍵字已經(jīng)封裝好了,很快捷方便。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/78598.html
摘要:基于原型的繼承原型上的屬性被共享了不是我們所需要的這種繼承會(huì)有如下的缺點(diǎn)如果父類包含有引用類型的屬性所有的子類就會(huì)共享這個(gè)屬性。 基于原型的繼承 function father() { this.faName = father; this.names=[11,22] } father.prototype.getfaName = fun...
摘要:原型鏈實(shí)現(xiàn)繼承例子繼承了借用構(gòu)造函數(shù)基本思想在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類構(gòu)造函數(shù),通過使用和方法可以在新創(chuàng)建的對(duì)象上執(zhí)行構(gòu)造函數(shù)。 前言:大多OO語言都支持兩種繼承方式:接口繼承和實(shí)現(xiàn)繼承,而ECMAScript中無法實(shí)現(xiàn)接口繼承,ECMAScript只支持實(shí)現(xiàn)繼承,而且其實(shí)現(xiàn)繼承主要是依靠原型鏈來實(shí)現(xiàn)。 1.原型鏈 基本思想:利用原型讓一個(gè)引用類型繼承另外一個(gè)引用類型的屬性和方法。...
摘要:原型繼承缺點(diǎn)子類實(shí)例共享屬性,造成實(shí)例間的屬性會(huì)相互影響可以看到子類的實(shí)例屬性皆來自于父類的一個(gè)實(shí)例,即子類共享了同一個(gè)實(shí)例共享了父類的方法構(gòu)造函數(shù)繼承缺點(diǎn)父類的方法沒有被共享,造成內(nèi)存浪費(fèi)子實(shí)例的屬性都是相互獨(dú)立的實(shí)例方法也是獨(dú)立的,沒有 原型繼承 缺點(diǎn): 子類實(shí)例共享屬性,造成實(shí)例間的屬性會(huì)相互影響 function Parent1() { this.name = [super...
摘要:使用最多的繼承模式是組合繼承,這種模式使用原型鏈繼承共享的屬性和方法,而借用構(gòu)造函數(shù)繼承實(shí)例屬性。原型式繼承,可以在不必預(yù)先定義構(gòu)造函數(shù)的情況下實(shí)現(xiàn)繼承,其本質(zhì)是執(zhí)行給定對(duì)象的淺復(fù)制。 1、原型鏈實(shí)現(xiàn)繼承 function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = func...
摘要:實(shí)現(xiàn)繼承的方法借用構(gòu)造函數(shù)解決原型中包含引用類型所帶來的問題的過程中,使用借用構(gòu)造函數(shù)偽造對(duì)象或經(jīng)典繼承來實(shí)現(xiàn)繼承。 繼承 在ECMAScript中繼承主要是依靠原型鏈來實(shí)現(xiàn)的。 實(shí)現(xiàn)繼承的方法 利用原型讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法 什么是原型鏈 先要了解構(gòu)造函數(shù)、原型、和實(shí)例的關(guān)系: 每一個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,實(shí)例都包含...
閱讀 830·2021-09-22 15:18
閱讀 1181·2021-09-09 09:33
閱讀 2758·2019-08-30 10:56
閱讀 1184·2019-08-29 16:30
閱讀 1488·2019-08-29 13:02
閱讀 1458·2019-08-26 13:55
閱讀 1643·2019-08-26 13:41
閱讀 1941·2019-08-26 11:56