考虑以下代码。
var book = {
name: "JavaScript Test Book",
edition: 3,
year: 2014
};
Object.defineProperty(book, "info", {
get: function() {
return "\"" + this.name + "\" edition " + this.edition + " published on " + this.year;
},
set: function(info) {
this.name = info[0];
this.edition = info[1];
this.year = info[2];
}
});
console.log(book.info); //"JavaScript Test Book" edition 3 published on 2014
book.info = ["JavaScript Recipe", 1, 2015];
console.log(book.info); //"JavaScript Recipe" edition 1 published on 2015
因此对于我的set属性,该函数只接受一个参数,即数组。这是我知道传递多个参数的唯一方法。
有没有其他方法可以传递多个参数? 所以我的设置功能可能是
set: function(name,edition,year) {
this.name = name;
this.edition = edition;
this.year = year;
}
答案 0 :(得分:4)
我认为你没有达到吸气剂/孵化器的目的。它不应该像函数一样工作,即使它是如何实现的。它应该像普通的属性一样工作,但有一些额外的控制,比如拒绝一个值。
对于你正在做的事情,你应该考虑继续使用一个功能。
这是更好地使用属性:
var book = {
name: "JavaScript Test Book",
edition: 3,
_year: 2014 // it'd be best to use a closure to ensure
// third-party code doesn't have access to
// your backing store
};
Object.defineProperty(book, "year", {
get: function() {
return this._year;
},
set: function(v) {
// Only assign the value if it's numeric
if ( !isNaN(parseFloat(v)) && isFinite(v) )
this._year = v;
else
throw 'Expecting a numeric value'; // be nice and make debugging easier
}
});
定义属性时,请务必遵循principle of least astonishment。如果我将一个数组分配给一个属性,我希望在访问该属性时能够获得该数组。将数组分配给属性并获取字符串是非常令人惊讶,并且肯定会导致非常难以诊断错误。
一般来说,我强烈建议不要在setter中改变一个值。如果用户正在为属性分配值,那么拒绝格式错误的值远比尝试修复它或以某种方式更改它更好。
想象一下,如果你运行以下代码但得到0结果,你会变得多么生气:
var u = new User();
u.FirstName = "Jon-Paul";
otherUsers.push( u );
// ... a thousand lines later ...
var JPs = otherUsers.filter(function(u){ return u.FirstName === "Jon-Paul"; });
您不知道的是,User对象的作者选择根据原始值到“JONPAU”的某些内部业务规则将FirstName
属性变更。想象一下,这将是多么困难的调试。现在想象一下,如果在分配FirstName
属性时出现一个简单的错误会有多么容易,例如:Error: FirstName must be all caps, contain characters A-Z and be no longer than 6 characters.