Javascript:如何从对象定义中正确创建新的自定义实例(如 class)

Javascript: How to correctly create a new custom istance from object definition (like a class)

我发现由于 IE11,仍然无法自由使用 class

所以我想使用 prototypesobject.create 以尽可能最轻便的方式创建我的 istances。 但是我只发现 Object.assign() 是一种对象合并而不是初始化器。

var classDefiner = {
   x: 1,
   y: 2,
   standardFunction : function() {
       return this.x+this.y;
   }
};

var istance = Object.assign({}, classDefiner ,{
    x: 10,
    z: 3,
    customFunctionA : function() {
        return this.x+this.y+this.z;
    },
    customFunctionB : function() {
        return this.x/this.y;
    }
});

老实说,这对我来说只是 {}classDefiner 所有方法的冗余副本。 prototypesclassobject.create() 的用处不大。 这是正确的方法还是我可以改进的地方?

PS:挑战是不要声明任何单个 function/method,而是使用 {} 包装器代替 class,另一个包装器用于 istance 为了可读性。我知道我可以使用 istance.newMethod 甚至 newobject.prototype.newMethod 手动添加许多方法。但是如果你有很多方法要添加的话,这会很长而且很乱。

我猜你是这个意思:

function classDefiner() {
   this.x = 1;
   this.y = 2;
};

classDefiner.prototype.standardFunction = function() {
       return this.x+this.y;
}

var a = new classDefiner();

a.standardFunction(); //3

如果您想通过复制 属性来完成此操作,那么您使用Object.assign 所做的可能与现在一样干净。 (请注意,您必须在 IE11 上填充 Object.assign,但它是完全可填充的。)一个调整是您可以使用方法语法而不是函数的 属性 初始化语法:

var instance = Object.assign({}, classDefiner ,{
    x: 10,
    z: 3,
    customFunctionA() {                 // ***
        return this.x+this.y+this.z;
    },
    customFunctionB() {                 // ***
        return this.x/this.y;
    }
});

ES2018 将为我们提供替换上面 Object.assign 的语法:

var instance = {
    ...classDefiner,                    // ***
    x: 10,
    z: 3,
    customFunctionA() {
        return this.x+this.y+this.z;
    },
    customFunctionB() {
        return this.x/this.y;
    }
};

(当然,如果不进行转译,那也无法在 IE11 上运行。:-))从技术上讲,the proposal for it 目前只是第 3 阶段,但可能会在几周后成为第 4 阶段在一月份的 TC39 会议之后,已经在 V8(Chrome)和 SpiderMonkey(在 Firefox)中实现。

如果你想通过继承来做到这一点,那么你在 Object.create 的正确轨道上:

var classDefiner = {
   x: 1,
   y: 2,
   standardFunction() {
       return this.x+this.y;
   }
};

var instance = Object.assign(Object.create(classDefiner), {
    x: 10,
    z: 3,
    customFunctionA() {
        return this.x+this.y+this.z;
    },
    customFunctionB() {
        return this.x/this.y;
    }
});

// Demonstrating it
console.log(instance.standardFunction());
console.log(instance.customFunctionA());

关于是只复制属性还是继承,我想说这两种方式都没有太多。

赞成继承:

  • 如果 创建 instance 之后,您添加或修改了 classDefiner,这些更改将反映在 instance 中(因为它继承而不是复制)。
  • 从技术上讲,使用继承而不是复制属性可能会稍微少一些内存使用,但除非您正在执行数百万次这样的操作,否则您不会关心它。

赞成复制:

  • Esp。至于上面提到的 属性 展开符号,语法更简洁。不过,您可以使用包装函数关闭。
  • 理论上,使用继承属性与复制 "own" 属性相比,可能会有 最小 额外开销,但我怀疑您在现代 JavaScript 引擎上需要关心的任何事情。