简体   繁体   English

ECMAScript 6中“扩展”原型的语法

[英]Syntax for “extending” Prototype in ECMAScript 6

Since classes in ECMAScript 6 is simply syntactical sugar over JavaScript's existing prototype-based inheritance, it is still possible to "extend" (for lack of a better word) the prototype of an existing class with EMCAScript 5 syntax and add methods to it even after the class declaration in a completely separate file. 由于ECMAScript 6中的类仅是JavaScript上现有的基于原型的继承的语法糖,因此仍然有可能使用EMCAScript 5语法“扩展”(缺少更好的词)现有类的原型,甚至在添加之后类声明位于完全独立的文件中。

/* Dog.js */

class Dog {
    woof() {
        console.log('woof woof');
    }
}

module.exports = Dog;

/* main.js */

var Dog = require('./Dog');

Dog.prototype.bark = function() {
    console.log('bark bark');
};

var dog = new Dog();
dog.woof(); // 'woof woof'
dog.bark(); // 'bark bark'

Is there a way to achieve the same functionality as above, but maintain the ECMAScript 6 class syntax in main.js as opposed to going back to the prototype syntax? 有没有一种方法可以实现与上述相同的功能,但是要在main.js维护ECMAScript 6类语法,而不是返回到原型语法? Trying something such as class Dog extends Dog throws an error as the Dog class is already declared. 尝试使用诸如class Dog extends Dog东西,因为已经声明了Dog类,因此会引发错误。

Note that this is not extending in the sense of inheritance, as that would require creating a new class rather than adding methods to an existing class. 请注意,这并没有在继承的意义上扩展,因为这将需要创建一个新类,而不是向现有类中添加方法。

class Dog {
    woof() {
        console.log('woof woof');
    }
}

class AdvancedDog extends Dog {
    bark() {
        console.log('bark bark');
    }
}

var dog = new Dog();
dog.woof(); // 'woof woof'
dog.bark(); // Error, not what is needed.

No, there's no way of doing what you want to achieve. 不,没有办法做您想达到的目标。

A class can't be partially declared across many files. 一个类不能在许多文件中部分声明。

BTW, you should be able to use some task runner like Grunt or Gulp and implement a task to merge many files declaring the same file that could generate a single file with a single class declaration from the other ones. 顺便说一句,您应该能够使用诸如Grunt或Gulp之类的任务运行器,并实现一个任务以合并许多文件,这些文件声明同一文件,而该文件可以使用其他文件中的单个类声明来生成单个文件。

Probably this could be also implemented as a Babel plugin. 可能也可以将其实现为Babel插件。

The semantics of extends is prototypical inheritance, while the wanted behaviour is prototype modification. extends的语义是原型继承,而所需的行为是原型修改。 It is not an everyday task and it is not something that has special syntax in ES6. 这不是日常任务,也不是ES6中具有特殊语法的内容。

It is possible to do this with 可以这样做

Object.assign(Dog.prototype, {
    bark() {
        console.log('bark bark');
    }
});

Notice that bark method in object literal is enumerable, while ES6 class methods are non-enumerable . 请注意,对象文字中的bark方法是可枚举的,而ES6类方法是不可枚举的 If this trait is crucial, Object.defineProperty should be additionally used. 如果此特征至关重要,则应另外使用Object.defineProperty

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM