扩展JavaScript中已定义的类 [英] Extend already defined class in JavaScript

查看:73
本文介绍了扩展JavaScript中已定义的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JS中扩展类的传统方式如下:

The traditional way of extending classes in JS is something like this:

// define constructor function
function Fuu(){}
// extend prototype and override prototype's constructor
Fuu.prototype = Object.create(OtherClass.prototype, {
    constructor: {
        value: Fuu, 
        enumerable: false, 
        writable: true, 
        configurable: true
    }
});

然后,然后将所需的方法添加到原型

Then you add the methods you want to the prototype

Fuu.prototype.method = function() {}

就像这样,您有一个扩展另一个功能的函数. JS中继承的一个很好的例子!

And just like that you have a function extending another. A nice example of inheritance in JS!

我的问题是,当子类已经具有带有方法和属性的原型时,如何扩展.我可以尝试使用for in循环将旧原型的方法复制到新原型,但是这些方法是不可枚举的(类是使用编译器创建的),并且使用getOwnPropertyNames做某事似乎不正确.有什么建议吗?我可以做些保留原型并将原型添加到原型的事情吗?

My question is how to extend when the sub class already has a prototype with methods and properties. I could try to copy the the methods of the old prototype to the new one using a for in loop but the methods are non enumerable(class is created with a transpiler) and doing something with getOwnPropertyNames doesn't seem right. Any suggestion? can I do something like keeping the prototype and adding a prototype to the prototype?

示例

class Fuu {
    someMethod(){} // non enumerable method in Fuu's prototype
}

// My first option: (extending this way `someMethod` is lost)
Fuu.protoype = Object.create(HTMLElement.prototype, {//...same as before})

// Option 2: copy methods from old to new prototype

// Option 3: prototype of prototype?
// Fuu.prototype.prototype = Object.create(HTMLElement.prototype, {...})

推荐答案

您想要类似的东西

            ┌──> Fuu.prototype
instances ──┤
            └──> OtherClass.prototype

但这是不可能的,因为对象只有一个[[Prototype]].

But that's not possible, because objects only have one [[Prototype]].

因此,您必须实现以下条件之一:

Therefore, you must achieve one of these:

instances ───> Fuu.prototype ───> OtherClass.prototype
instances ───> OtherClass.prototype ───> Fuu.prototype

因此,您必须将其中一个的[[Prototype]]设置为另一个.我将假设第一种可能性.

So you must set the [[Prototype]] of one of those to be the other one. I will assume the first possibility.

设置[[Prototype]]的主要方法有两种:

There are two main ways to set the [[Prototype]]:

  • Object.create, when creating the object

问题在于Fuu.prototypeOtherClass.prototype都已经创建.

The problem is that both Fuu.prototype and OtherClass.prototype have been created already.

但是,您可以使用右侧的[[Prototype]]创建一个新对象并分配旧对象的属性.

However, you can create a new object with the right [[Prototype]] and assign the properties of the old one.

由于可能存在不可枚举的属性,因此必须使用 getOwnPropertyNames .使用 defineProperty getOwnPropertyDescriptor 可能也是一个好主意,以防有吸气剂或吸气剂.

Since there may be non-enumerable properties, you must use getOwnPropertyNames. Using defineProperty and getOwnPropertyDescriptor may also be a good idea, in case there are getters or setters.

var old = Fuu.prototype,
    props = Object.getOwnPropertyNames(old);
Fuu.prototype = Object.create(OtherClass.prototype);
for(var i=0; i<props.length; ++i)
   Object.defineProperty(
     Fuu.prototype,
     props[i],
     Object.getOwnPropertyDescriptor(old, props[i])
   );

  • setPrototypeOf __proto__ ( ES6),一旦创建了对象:

  • setPrototypeOf or __proto__ (ES6), once the object has been created:

    Object.setPrototypeOf(Fuu.prototype, OtherClass.prototype);
    

    Fuu.prototype.__proto__ = OtherClass.prototype;
    

    但是,请注意

    根据对象的性质,更改对象的[[Prototype]] 现代的JavaScript引擎优化了属性访问,这非常慢 每个浏览器和JavaScript引擎中的操作.对的影响 变异原型的性能可能会扩展到任何代码, 有权访问其[[Prototype]]已被更改的任何对象.如果你 在乎性能时,您应该避免使[ 一个对象.

    Mutating the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of mutating prototypes [...] may extend to any code that has access to any object whose [[Prototype]] has been mutated. If you care about performance you should avoid mutating the [[Prototype]] of an object.

  • 这篇关于扩展JavaScript中已定义的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆