资讯专栏INFORMATION COLUMN

js中的几种继承实现

时飞 / 1134人阅读

摘要:使用关键字熟悉的同学应该非常熟悉这个关键字,中的继承都是靠它实现的。新加入的关键字是语法糖,本质还是函数使用修改之前的例子,将会更简单在下面的例子,定义了一个名为的类,然后定义了一个继承于的类。

使用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为将要被设置原型的一个对象
prototypeobj新的原型(可以是一个对象或者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关键字是语法糖,本质还是函数.

使用extends修改之前util.inherits的例子,将会更简单

const EventEmitter = require("events");

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on("event", function() {
  console.log("an event occurred!");
});
myEmitter.emit("event");

在下面的例子,定义了一个名为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";
  }
}

使用关键字后就不用婆婆妈妈各种设置原型了,关键字已经封装好了,很快捷方便。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78598.html

相关文章

  • 面试--js实现继承几种方式

    摘要:基于原型的继承原型上的属性被共享了不是我们所需要的这种继承会有如下的缺点如果父类包含有引用类型的属性所有的子类就会共享这个属性。 基于原型的继承 function father() { this.faName = father; this.names=[11,22] } father.prototype.getfaName = fun...

    baiy 评论0 收藏0
  • js实现继承几种方式

    摘要:原型链实现继承例子继承了借用构造函数基本思想在子类型构造函数的内部调用超类构造函数,通过使用和方法可以在新创建的对象上执行构造函数。 前言:大多OO语言都支持两种继承方式:接口继承和实现继承,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现。 1.原型链 基本思想:利用原型让一个引用类型继承另外一个引用类型的属性和方法。...

    Alliot 评论0 收藏0
  • JS继承实现几种方式及其优缺点

    摘要:原型继承缺点子类实例共享属性,造成实例间的属性会相互影响可以看到子类的实例属性皆来自于父类的一个实例,即子类共享了同一个实例共享了父类的方法构造函数继承缺点父类的方法没有被共享,造成内存浪费子实例的属性都是相互独立的实例方法也是独立的,没有 原型继承 缺点: 子类实例共享属性,造成实例间的属性会相互影响 function Parent1() { this.name = [super...

    ymyang 评论0 收藏0
  • JS学习笔记(第6章)(实现继承几种方式)

    摘要:使用最多的继承模式是组合继承,这种模式使用原型链继承共享的属性和方法,而借用构造函数继承实例属性。原型式继承,可以在不必预先定义构造函数的情况下实现继承,其本质是执行给定对象的浅复制。 1、原型链实现继承 function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = func...

    hiyayiji 评论0 收藏0
  • js实现继承几种方法

    摘要:实现继承的方法借用构造函数解决原型中包含引用类型所带来的问题的过程中,使用借用构造函数伪造对象或经典继承来实现继承。 继承 在ECMAScript中继承主要是依靠原型链来实现的。 实现继承的方法 利用原型让一个引用类型继承另一个引用类型的属性和方法 什么是原型链 先要了解构造函数、原型、和实例的关系: 每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,实例都包含...

    pkhope 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<