Javascript 在构造函数中创建只读(get)属性
我试图用Javascript在构造函数上创建一个只读属性。我已经混音了,但这不起作用:Javascript 在构造函数中创建只读(get)属性,javascript,Javascript,我试图用Javascript在构造函数上创建一个只读属性。我已经混音了,但这不起作用: 职能人员(数据){ var self=这个; self.firstName=data.firstName | |“John”; self.lastName=data.lastName | |“Doe”; get fullName(){return self.firstName+“”+self.lastName;} } var mike=新人({firstName:“mike”,lastName:“Michae
职能人员(数据){
var self=这个;
self.firstName=data.firstName | |“John”;
self.lastName=data.lastName | |“Doe”;
get fullName(){return self.firstName+“”+self.lastName;}
}
var mike=新人({firstName:“mike”,lastName:“Michaelson”});
document.write(mike.fullName);
这将引发异常:
未捕获的语法错误:意外的标识符
我尝试过其他选择,包括:
{ get fullName() { return self.firstName + " " + self.lastName; } }
以及:
以及:
但这些选项都不起作用
这一个确实有效:
职能人员(数据){
var self=这个;
self.firstName=data.firstName | |“John”;
self.lastName=data.lastName | |“Doe”;
defineProperty(self,“fullName”,{get:function(){return self.firstName+“”+self.lastName;}}});
}
var mike=新人({firstName:“mike”,lastName:“Michaelson”});
document.write(mike.fullName)
我建议将其设置为一个POJO,并始终传递选项,但您仍然会有Object.defineProperties
的“笨拙”,只是没有实际调用它的仪式(我个人更喜欢速记方式)
EDIT:现在我已经详细考虑了它,我认为您想要包含defineProperty
语法的原因是您想要对名字和姓氏具有读/写访问权限,但对全名具有只读访问权限。如果这个假设是正确的,我通常会使用这个模式
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'
我通常更喜欢将参数作为不可变的东西传入,或者通过将这些特性从对象复制到不可变的东西中来冻结这些特性,这样通过对象引用进行的更新不会在您的行为中造成细微的错误。您可以将其放入原型中(object.prototype={get x(){返回这个。x;}
-但是在声明完整原型时只能执行一次)或者使用defineProperty
。如果要创建只读属性,实际上应该使用defineProperty
使其不可写。这是唯一有效的语法方法。@Jeroen您是否希望对名/姓具有读/写权限,但对fullName
具有只读权限?如果是,请重新读取my答案,因为我已经更新了它以适应这种情况。@Drogans感谢您的想法和想法。您对读/写访问的假设是正确的,尽管我已经能够从您对这些情况的原始答案中推断出来。我对您的答案投了更高的票,它很有用,但它并不是我问题的答案,因为您是人
函数不再用作构造函数,因为它破坏了继承。-我想我只是被C#的属性语法破坏了…所以基本上“不可能在构造函数本身中使用速记”?另一方面,在您的示例中,返回的POJO的原型应该是对象
,而不是人
,对吗?如果您运行这个,并询问人。原型
,它会说它是人
对象。如果您愿意,您也可以新建它。它的行为应该与您的问题中的代码示例完全相同如上所述。(new Person())instanceof Person;
,与之相反。我可能误解了什么?不,你没有误解,返回的对象实际上就是{}
对象。允许轻松定义的唯一方法是正确使用原型并在那里添加getter和setter,或者使用defineProperty
。您正在寻找Javascript中不存在的语法糖。@Jeroen您是对的!我没有意识到instanceof
不起作用。这似乎是一个不同的赌注在这两个实现之间。
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; }
}
}
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'