在构造函数中创建只读(get)属性

时间:2015-12-30 14:52:49

标签: javascript

我尝试使用Javascript在构造函数上创建只读属性。我已经重新混合the syntax I've found on MDN,但这不起作用:

function Person(data) {
  var self = this;

  self.firstName = data.firstName || "John";
  self.lastName = data.lastName || "Doe";

  get fullName() { return self.firstName + " " + self.lastName; }
}

var mike = new Person({ firstName: "Mike", lastName: "Michaelson" });

document.write(mike.fullName);

这将抛出异常:

  

未捕获的SyntaxError:意外的标识符

我尝试了其他选择,包括:

{ get fullName() { return self.firstName + " " + self.lastName; } }

get this.fullName() { return self.firstName + " " + self.lastName; } 

get self.fullName() { return self.firstName + " " + self.lastName; } 

但这些选项都不起作用。

这个 工作:



function Person(data) {
  var self = this;

  self.firstName = data.firstName || "John";
  self.lastName = data.lastName || "Doe";
  
  Object.defineProperty(self, "fullName", { get: function () { return self.firstName + " " + self.lastName; } });
}

var mike = new Person({ firstName: "Mike", lastName: "Michaelson" });

document.write(mike.fullName);




但显然这种方式defineProperty感觉很笨拙。

定义get的正确语法是什么 - 只有构造函数内的属性?

1 个答案:

答案 0 :(得分:1)

我建议把它作为一个POJO,一路上传递选项,但你仍然会有Object.defineProperties的“笨拙”,只是没有实际召唤它的仪式(我喜欢速记方式更好,亲自)。

var Person = function (data) {
    if (data === undefined) {
        data = {};
    }

    data = _.defaults(data, {
        firstName: 'John',
        lastName: 'Doe'
    });

    return {
        get firstName() { return data.firstName; },
        get lastName() { return data.lastName; },
        get fullName() { return data.firstName + ' ' + data.lastName; }
    }
}

编辑:现在我已经考虑过了更多,我认为您想要包含defineProperty语法的原因是因为您希望拥有读/写权限名字和姓氏,但对fullName的只读访问权限。如果这个假设是正确的,那么这是我通常会使用的模式。

var Person = function (data) {
    if (data === undefined) {
        data = {};
    }

    data = _.defaults(data, {
        firstName: 'John',
        lastName: 'Doe'
    });

    return {
        get firstName() { return data.firstName; },
        set firstName(name) { data.firstName = name; },

        get lastName() { return data.lastName; },
        set lastName(name) { data.lastName = name; },

        get fullName() { return data.firstName + ' ' + data.lastName; }
    }
}

p = Person();
p.fullName === 'John Doe'; // true
p.firstName = 'Jane';
p.fullName === 'Jane Doe'; // true

但是,有一些需要注意的注意事项,主要是对象引用。

data = { firstName: 'Jane' };
p = Person(data);
p.fullName === 'Jane Doe'; // true
data.lastName = 'Goodall';
p.fullName === 'Jane Doe'; // false!
console.log(p.fullName); // 'Jane Goodall'

我通常更喜欢将参数作为不可变的东西传入,或者通过将它们从对象复制到不可变的东西来冻结这些特征,以便通过对象引用进行更新不会导致行为中的细微错误。