我正在学习JavaScript(在64位Debian Jessie上使用最新的Google Chrome构建版本),现在已经有几天了,现在我仍然在理解Object.defineProperty
的确切运作方式。我有以下页面:
function createPerson() {
var person = {
firstName: 'Lilly',
lastName: 'Louis',
};
Object.defineProperty(person, 'fullName', {
get: function() {
return this.firstName + ' ' + this.lastName;
},
set: function(name) {
var words = name.split(' ');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
});
}
var p1 = createPerson();
console.log("Person's default name is \"" + p1.fullName + "\"");
我在{I}尝试使用Uncaught TypeError: Cannot read property 'fullName' of undefined
内的属性的行中得到console.log(...)
。如果我将person
的定义和Object.defineProperty
放在函数外部,一切正常。如果我在Object.defineProperty
之后创建了 p1
,请执行此操作:
var p1 = createPerson();
Object.defineProperty(p1, 'fullName', {
get: function() {
return this.firstName + ' ' + this.lastName;
},
set: function(name) {
var names = name.split(' ');
this.firstName = names[0] || '';
this.lastName = names[1] || '';
}
});
我得到Uncaught TypeError: Object.defineProperty called on non-object
,然后控制台指出它是在(anonymous function)
(即p1
)上调用的,这更加令人困惑,因为我刚才读到了如果我将callPerson
分配给我的p1
而没有括号我正在将函数对象传递给它,否则我正在调用函数本身并分配其返回值(如果没有, undefined 被退回)p1
。
我觉得这两个问题完全是分开的,但我仍然不能100%肯定我已经决定将两者放在同一个问题上。我在这里做错了什么建议?我可以通过简单地执行
来定义我的getter
和setter
旧式方式
function createPerson() {
var person = {
firstName: 'Lilly',
lastName: 'Louis',
getFullName: function() {
return ...;
}
setFullName: function(name) {
...
}
};
}
但我想了解这里发生了什么。 :d
答案 0 :(得分:4)
您的defineProperty
电话绝对没问题。问题是createPerson
永远不会返回任何内容,因此调用它的结果是undefined
。你最后想要return person;
:
function createPerson() {
var person = {
firstName: 'Lilly',
lastName: 'Louis',
};
Object.defineProperty(person, 'fullName', {
get: function() {
return this.firstName + ' ' + this.lastName;
},
set: function(name) {
var words = name.split(' ');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
});
return person; // <=======
}
var p1 = createPerson();
console.log("Person's default name is \"" + p1.fullName + "\"");
&#13;
或者,将其设为构造函数函数(与new
一起使用)而不是工厂函数,并在函数中使用this
。在这种情况下,我们会从名称中删除create
,而我们最终不会(通常)使用return this;
,因为如果该功能没有返回不同的名称对象,默认情况下new XYZ
的结果是new
运算符创建的对象,并作为this
提供给函数:
function Person() {
this.firstName = 'Lilly';
this.lastName = 'Louis';
Object.defineProperty(this, 'fullName', {
get: function() {
return this.firstName + ' ' + this.lastName;
},
set: function(name) {
var words = name.split(' ');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
});
}
var p1 = new Person();
console.log("Person's default name is \"" + p1.fullName + "\"");
&#13;
答案 1 :(得分:1)
这是因为你创建了一个person
变量,但从未返回它。因此,函数没有返回任何内容,并且赋值未定义:
function createPerson() {
var person = {
firstName: 'Lilly',
lastName: 'Louis',
};
Object.defineProperty(person, 'fullName', {
get: function() { return this.firstName + ' ' + this.lastName; },
set: function(name) {
var words = name.split(' ');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
});
return person; // Add this line
}