添加除访问器之外的函数的语法是什么?

时间:2016-03-31 10:14:36

标签: javascript node.js oop factory

我正在学习使用Node的JavaScript。我喜欢用工厂创建对象的想法,在阅读了很多关于这个主题的内容后,我选择用这段代码创建对象:

// ES6 only
'use strict';

// The base object, "object literal" syntax
let animal2 = {
  // public member
  animalType: 'animal',

  // public method 
  describe() {
    return `This is "${this.animalType}"`;
  }
};

// factory function which serves 2 purposes:
// - encapsulation, that's where private things are declared thanks to closures
// - the "real" object creation, this prevents to use "new" which is not really Js-ish
let afc = function afc() {
  // private member
  let priv = "secret from afc";

  return Object.create(animal2, {
    // Object customisation
    animalType: { value: 'animal with create'},    

    // object extension. The new objects created here get 3 new members:
    // - a private member
    // - a new property
    // - a new method to access the private member

    // new public member
    color: { value: 'green' },
    secret: {
      get: function () { return priv; },
      set: function (value) { priv = value; },
    },
    KO1() {
      console.log("KO1");
    },
    KO2: function() {
      console.log("KO2");
    }
  });
}

// creation of an animal instance
let tac = afc();

我的问题是我无法弄清楚添加一个可以操作私有数据而不仅仅是一个访问者的函数的语法是什么。我在这里提到了2个我想到的例子(KOx),但正如他们的名字所暗示的那样,这种语法导致:“KOx不是一个函数”。

2 个答案:

答案 0 :(得分:2)

Object.create期望将属性描述符的对象作为其第二个参数。这就是您必须在任何地方使用{value: …}{set: …, get: …}的原因。

事实上,你必须为一个方法做同样的事情 - 这只是一个标准属性,其函数作为其值:

…
KO3: {value: function() {
    …
}},
…

但是,当您不需要时,我会避免使用属性描述符。 Object.assign更合适:

return Object.assign(Object.create(animal2, {
    secret: {
        get() { return priv; },
        set(value) { priv = value; },
    }
}), {
    animalType: 'animal with create',
    color: 'green',
    KO1() {
        console.log("KO1");
    },
    KO2: function() {
        console.log("KO2");
    }
});

答案 1 :(得分:0)

为什么不使用getter语法?

return {
  __proto__: animal2, // To be honest __proto__ is not a good thing to use

  animalType: 'animal with create',

  color: 'green',
  get secret() { return priv; },
  set secret(value) { priv = value; },
  get KO3() { console.log("KO3"); },
  // or just the following, if you would like it to be a regular member function
  // KO3() { console.log("KO3"); },
};

或没有明确的__proto__

const result = {
  animalType: 'animal with create',

  color: 'green',
  get secret() { return priv; },
  set secret(value) { priv = value; },
  get KO3() { console.log("KO3"); },
};
Object.setPrototypeOf(result, animal2);
return result;