首頁  >  文章  >  web前端  >  javascript中的3種繼承實作方法_基礎知識

javascript中的3種繼承實作方法_基礎知識

WBOY
WBOY原創
2016-05-16 15:17:441120瀏覽

使用Object.create實作類別繼承

以下是官網的例子

//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."

此時Rectangle原型的constructor指向父類,如需要使用自身的構造,手動指定即可,如下

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!"

也很簡單的例子,其實源碼用了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新特性,將一個指定的物件的原型設定為另一個物件或null

文法

Object.setPrototypeOf(obj, prototype)
obj為將要被設定原型的一個物件
prototype為obj新的原型(可以是一個物件或null).

如果設定成null,即為如下範例

Object.setPrototypeOf({}, null);
感覺setPrototypeOf真是人如其名啊,專門搞prototype來玩。
那麼這個玩意又是如何實現的呢?此時需藉助宗師__proto__

Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
 obj.__proto__ = proto;
 return obj; 
}

即把proto賦給obj.__proto__就好了。

使用extends關鍵字

熟悉java的同學應該要非常熟悉這個關鍵字,java中的繼承都是靠它實現的。
ES6新加入的class關鍵字是語法糖,本質還是函數.

在下面的例子,定義了一個名為Polygon的類,然後定義了一個繼承於Polygon的類別 Square。注意到在建構器使用的 super(),supper()只能在建構器中使用,super函數一定要在this可以使用之前呼叫。

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';
 }
}

使用關鍵字後就不用婆婆媽媽各種設定原型了,關鍵字已經封裝好了,很快速方便。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn