使对象的所有属性可变
Make all properties of object mutable
我如何定义一个对象的属性,以便如果更改其中一个属性,则所有其他属性都会自动更新。
到目前为止我已经想出了这段代码,但它不起作用:
function CreateNamed(first, last) {
Object.defineProperties(this, {
"firstName": {
value: first,
writable: true
},
"lastName": {
value: last,
writable: true
},
"fullName": {
value: first + ' ' + last,
writable: true
}
});
}
所以在创建一个新的对象后,可以适当地改变它:
var b = new CreateNamed('Bill', 'Gates'); // Bill Gates
b.firstName = 'Paul'; // b.fullName = Paul Gates
b.lastName = 'Wood'; // b.fullname = Paul Wood
b.fullName = 'Chuck Norris' // b.firstName = Chuck, b.lastName = Norris
value
不是动态计算的。它不会随着对象的改变而改变。为了动态计算属性,您需要使用 get
and set
:
定义 getter 和 setter
get
A function which serves as a getter for the property, or undefined if there is no getter. The function return will be used as
the value of property. Defaults to undefined.
set
A function which serves as a setter for the property, or undefined if there is no setter. The function will receive as only
argument the new value being assigned to the property. Defaults to
undefined.
function CreateNamed(first, last) {
this.first = first;
this.last = last;
Object.defineProperties(this, {
"firstName": {
get: function() { return this.first; },
set: function(name) { this.first = name; }
},
"lastName": {
get: function() { return this.last; },
set: function(name) { this.last = name; }
},
"fullName": {
get: function () { return this.first + ' ' + this.last },
set: function (name) {
if (!name.match(/^[a-z]+ [a-z]+$/))
throw new Error('I cannot parse that name')
var parts = name.split(' ')
this.first = parts[0];
this.last = parts[1];
}
}
});
}
var user = new CreateNamed('bob', 'smith');
document.write(user.fullName); // bob smith
user.firstName = "john";
document.write(user.fullName); // john smith
user.fullName = "tony brian";
document.write(user.firstName); // tony
document.write(user.lastName); // brian
正确。
但是有一个更简单的方法:像往常一样分配firstName
和lastName
属性,然后只为[=14定义一个getter和setter =]:
function CreateNamed(first, last) {
this.firstName = first;
this.lastName = last;
Object.defineProperty(this, "fullName", {
get: function () { return this.firstName + ' ' + this.lastName },
set: function (name) {
name = name.split(' ');
if(name.length != 2) throw new Error('I cannot parse that name');
this.firstName = name[0];
this.lastName = name[1];
}
});
}
function CreateNamed(first, last) {
this.firstName = first;
this.lastName = last;
Object.defineProperty(this, "fullName", {
get: function () { return this.firstName + ' ' + this.lastName },
set: function (name) {
name = name.split(' ');
if(name.length != 2) throw new Error('I cannot parse that name');
this.firstName = name[0];
this.lastName = name[1];
}
});
}
var ouput = [];
var user = new CreateNamed('bob', 'smith');
ouput.push(user.fullName); // bob smith
user.firstName = "john";
ouput.push(user.fullName); // john smith
user.fullName = "tony brian";
ouput.push(user.firstName); // tony
ouput.push(user.lastName); // brian
document.body.innerHTML = ouput.join('<br />');
我如何定义一个对象的属性,以便如果更改其中一个属性,则所有其他属性都会自动更新。
到目前为止我已经想出了这段代码,但它不起作用:
function CreateNamed(first, last) {
Object.defineProperties(this, {
"firstName": {
value: first,
writable: true
},
"lastName": {
value: last,
writable: true
},
"fullName": {
value: first + ' ' + last,
writable: true
}
});
}
所以在创建一个新的对象后,可以适当地改变它:
var b = new CreateNamed('Bill', 'Gates'); // Bill Gates
b.firstName = 'Paul'; // b.fullName = Paul Gates
b.lastName = 'Wood'; // b.fullname = Paul Wood
b.fullName = 'Chuck Norris' // b.firstName = Chuck, b.lastName = Norris
value
不是动态计算的。它不会随着对象的改变而改变。为了动态计算属性,您需要使用 get
and set
:
get
A function which serves as a getter for the property, or undefined if there is no getter. The function return will be used as the value of property. Defaults to undefined.set
A function which serves as a setter for the property, or undefined if there is no setter. The function will receive as only argument the new value being assigned to the property. Defaults to undefined.
function CreateNamed(first, last) {
this.first = first;
this.last = last;
Object.defineProperties(this, {
"firstName": {
get: function() { return this.first; },
set: function(name) { this.first = name; }
},
"lastName": {
get: function() { return this.last; },
set: function(name) { this.last = name; }
},
"fullName": {
get: function () { return this.first + ' ' + this.last },
set: function (name) {
if (!name.match(/^[a-z]+ [a-z]+$/))
throw new Error('I cannot parse that name')
var parts = name.split(' ')
this.first = parts[0];
this.last = parts[1];
}
}
});
}
var user = new CreateNamed('bob', 'smith');
document.write(user.fullName); // bob smith
user.firstName = "john";
document.write(user.fullName); // john smith
user.fullName = "tony brian";
document.write(user.firstName); // tony
document.write(user.lastName); // brian
但是有一个更简单的方法:像往常一样分配firstName
和lastName
属性,然后只为[=14定义一个getter和setter =]:
function CreateNamed(first, last) {
this.firstName = first;
this.lastName = last;
Object.defineProperty(this, "fullName", {
get: function () { return this.firstName + ' ' + this.lastName },
set: function (name) {
name = name.split(' ');
if(name.length != 2) throw new Error('I cannot parse that name');
this.firstName = name[0];
this.lastName = name[1];
}
});
}
function CreateNamed(first, last) {
this.firstName = first;
this.lastName = last;
Object.defineProperty(this, "fullName", {
get: function () { return this.firstName + ' ' + this.lastName },
set: function (name) {
name = name.split(' ');
if(name.length != 2) throw new Error('I cannot parse that name');
this.firstName = name[0];
this.lastName = name[1];
}
});
}
var ouput = [];
var user = new CreateNamed('bob', 'smith');
ouput.push(user.fullName); // bob smith
user.firstName = "john";
ouput.push(user.fullName); // john smith
user.fullName = "tony brian";
ouput.push(user.firstName); // tony
ouput.push(user.lastName); // brian
document.body.innerHTML = ouput.join('<br />');