尝试反序列化JSON数据并更新每个对象的原型并继承一个通用函数。
但是,以下脚本抛出错误“people [0] .getFullName不是函数”。在分配后,反序列化对象的原型似乎未定义。
<html>
<head>
<script>
var json = '[ {"firstName": "John", "lastName": "Smith"}, {"firstName": "Nancy", "lastName": "Jones"} ]';
var people;
eval('people = ' + json);
function Person() { }
Person.prototype.getFullName = function() {
return this.firstName + ' ' + this.lastName;
}
//assign prototype
for(var i=0; i < people.length; i++){
people[i].prototype = new Person();
}
if(people[0].getFullName() !== 'John Smith')
alert('Expected fullname to be John Smith but was ' + people[0].getFullName());
</script>
</head>
</html>
答案 0 :(得分:4)
由x = new Person()创建的对象x链接到/继承自Person.prototype,但就ecma标准而言,您无法按顺序更改x.prototype之后改变那个链接/继承,这只是 new 关键词拥有的“神奇力量”。
Mozilla似乎提供了一种在通过非标准属性__proto__创建对象后更改对象链接的方法。
Mozilla的只有:
//assign prototype
for(var i=0; i < people.length; i++){
people[i].__proto__ = Person.prototype;
}
应该在任何地方工作:
function Person(data) { this.data = data; }
Person.prototype.getFullName = function() {
return this.data.firstName + ' ' + this.data.lastName;
}
eval('people = ' + json);
//assign prototype
for(var i=0; i < people.length; i++){
people[i] = new Person(people[i]);
}
答案 1 :(得分:2)
prototype
属性是构造函数的属性,而不是实例的属性。您要找的是 __proto__
:
people[i].__proto__ = new Person();
坏消息是在所有浏览器中都不起作用。它在Firefox和Safari中有效,但在IE中不起作用。另一种方法是使用构造函数来实例化您的数组。不幸的是,你必须复制所有属性:
function Person(obj) {
for (var property in obj) {
this[property] = obj[property];
}
return this;
}
Person.prototype.getFullName = function() {
return this.firstName + ' ' + this.lastName;
}
var people;
eval('people = ' + json);
for(var i=0; i < people.length; i++) {
people[i] = new Person(people[i]);
}
答案 2 :(得分:2)
基本上,您必须将JSON对象INTO一个Person对象,然后getFullName才适用。我已经重写了你的工作。可能还有更好的方法,但我认为这是你打算做的......
<html>
<head>
<script>
//NOTE: Sending around JSON arrays leaves bad security holes for non-IE browsers (__defineSetter__)
var json = '[ {"firstName": "John", "lastName": "Smith"}, {"firstName": "Nancy", "lastName": "Jones"} ]';
//Persons is just a temporary JSON array
var persons = eval(json);
//constructor takes optional object instance and copies all properties if it gets one
function Person(person) {
if (person) {
for(var prop in person)
this[prop] = person[prop];
}
}
//Prototype applies to all Person objects
Person.prototype.getFullName = function() {
return this.firstName + ' ' + this.lastName;
}
//Create People array
var people = new Array();
for(var i=0; i < persons.length; i++){
people[i] = new Person(persons[i]);
}
//Now do your check
if(people[0].getFullName() !== 'John Smith')
alert('Expected fullname to be John Smith but was ' + people[0].getFullName());
</script>
</head>
</html>
答案 3 :(得分:2)
for(var i=0; i < people.length; i++){
people[i].getFullName = Person.prototype.getFullName; }