2014-04-17 102 views
5

假设我对人物具有以下JSON。将原型附加到JavaScript对象

[ 
    { 
    "name": "Alice", 
    "age": 28, 
    }, 
    { 
    "name": "Bob", 
    "age": 33 
    } 
] 

如果我解析这个,我将得到一个包含两个JavaScript对象的数组。 比方说,我要装备一个叫做介绍方法这两个对象,这并不像这样

function introduce() { 
    return "My name is " + this.name + " and I am " + this.age + " years old."; 
} 

现在,我可以遍历我的两个人,并呼吁

person.constructor.prototype.introduce = introduce 

然而,这将在所有JavaScript对象中公开引入函数,而不仅仅是上述两个。

我也可以手动将函数附加到每个对象上,但是如果我想用额外的函数扩展我的人员,我将不得不遍历所有人。理想情况下,我想要一个原型,我可以适应introduce方法,然后将这个原型附加到我的所有人,所以如果我后来扩展原型,我的人也将获得更多的功能。

问题是:如何?

+1

只是'person.prototype.introduce =介绍'并摆脱'构造函数'部分。 –

+1

为什么不做一个'Person'类,解析json来创建'Person'。随时将任何函数添加到'Person'原型。 – mshsayem

+0

@BrianGlaz:我认为'person'是他对对象本身的引用,所以'person.prototype'将不存在。 –

回答

3

您可以使用已弃用__proto__属性或ES6方法Object.setPrototypeOf。请注意,强烈不鼓励突变对象的原型(c.f. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),但它似乎是合法的用例。

var you = { name: "Niels B." } 
you.__proto__ = { hello: function() { console.log(this.name) } } 
you.hello() 

因此,对于您的具体问题:

function Person() {} 
Person.prototype = { 
    introduce: function() { 
    return "My name is " + this.name + " and I am " + this.age + " years old."; 
    } 
} 

然后为每个人:

person.__proto__ = Person.prototype; 
// or 
Object.setPrototypeOf(person, Person.prototype); 

这里有一个相关的JSPerf:http://jsperf.com/parse-json-into-an-object-and-assign-a-prototype

相关主题:https://groups.google.com/forum/#!topic/ringojs/PxS1O5jMx-8

+1

这将该方法添加到Object.prototype。该问题指出他不想将该方法添加到所有对象。 –

+0

@cookiemonster很确定它不会,它只会改变对象的原型。 – Aegis

+0

该对象的原型是'Object.prototype'。 http://jsfiddle.net/sdQwQ/ –

3

我建议你创建一个类:

JSBin

var Person = (function() { 
    function Person(person) { 
     this.person = person; 
     this.name = person.name; 
     this.age = person.age; 
    } 
    Person.prototype.introduce = function() { 
     return "My name is " + this.name + " and I am " + this.age + " years old."; 
    }; 
    return Person; 
})(); 
+0

嘿!可能是一个愚蠢的问题,但是将它包装在IIFE中的原因是什么? – Aegis

+2

@Aegis私有变量和方法! – Beterraba

3

你的问题有点模糊的了解。但我认为你不希望你的“人”是一个普通的对象,而是一个独立的人“类:”

var Person = function(obj){ 
    this.name = obj.name; 
}; 

Person.prototype.introduce = function(){ 
    return console.log('hi, I\'m '+this.name); 
}; 

var personA = new Person({ name:'a' }); 
var personB = new Person({ name:'b' }); 

personA.introduce(); // "hi, I'm a" 
personB.introduce(); // "hi, I'm b" 
+1

所以基本上得出的结论是,不可能将原型优雅地分配给现有的(文字)对象。相反,必须使用构造函数创建新对象。 –

+0

@NielsB。好吧,虽然可能,但你不会这么做,因为你只想'介绍'可用于_certain_对象,在我的例子中是'Person'实例。 – rgthree

+0

是的,我知道。我不想替换所有对象的原型,但直观地看来,迭代数组并替换原型引用而不是创建一组全新对象似乎更有效。 –

3

做一个简单的Person类:

function Person(name,age){ 
    this.name = name; 
    this.age = age 
} 

说,你有这样的阵列:

var people = [ 
    { 
    "name": "Alice", 
    "age": 28, 
    }, 
    { 
    "name": "Bob", 
    "age": 33 
    } 
]; 

转换peoplePerson数组:

people = people.map(function(p){ 
    return new Person(p.name,p.age) 
}); 

的方法添加到原型:

Person.prototype.introduce = introduce 
2

创建人类,并使用Person.prototype的:

function Person(name, age){ 
    this.name = name; 
    this.age= age; 
} 

function introduce() { 
    return "My name is " + this.name + " and I am " + this.age + " years old."; 
} 

Person.prototype.introduce = introduce; 

p1 = new Person ("bob", 33); 
p1.introduce(); 
1

我建议建立对这些人的结构。

var Person = function Person(init){ 
this.name = init.name; 
this.age = init.age; 
}; 
Person.constructor = Person; 

然后迭代构建人员。

var people = []; 
for(var i = 0; i < yourJson.length; i++){ 
people.push(new Person(yourJson[i])); 
} 

现在人们都建了,也许你想让他们能够介绍一下自己。你可以简单地扩展你的Person“类”(定义)。

Person.prototype.introduce = function() { 
    return "My name is " + this.name + " and I am " + age + " years old."; 
} 

,这将使他们能够使用此功能

for(var i = 0; i < people.length; i++){ 
console.log(people[i].introduce()); 
} 
1

如果你不想重新构建每次你可以试试这个时间:

var people =[ 
    { 
    "name": "Alice", 
    "age": 28, 
    }, 
    { 
    "name": "Bob", 
    "age": 33 
    } 
], 
i=-1,len=people.length,tmp 
,proto={ 
    sayName: function(){ 
    console.log("from sayname",this.data.name); 
    } 
}; 
while(++i<len){ 
    tmp=Object.create(proto); 
    tmp.data=people[i]; 
    people[i]=tmp; 
} 
people[0].sayName(); 
proto.sayName=function(){console.log("changed it");}; 
people[1].sayName(); 

如果你的JSON对象有许多成员可以避免将它们复制到构造函数中,但我不确定是否可以获得更多性能。