2014-04-17 139 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對象有許多成員可以避免將它們複製到構造函數中,但我不確定是否可以獲得更多性能。