2012-08-04 19 views
13
function Person() { 
     var self = this; 

     self.personName=""; 
     self.animals=[]; 
} 

function Animal(){ 
    var self=this; 

    self.animalName=""; 
    self.run=function(meters){ 
     ..... 
    } 
} 

उदाहरणों कार्य करने के लिए ("वर्गों"):सादा वस्तुओं कास्टिंग सर्वर प्रतिक्रिया जावास्क्रिप्ट में

[{personName:John,animals:[{animalName:cheetah},{animalName:giraffe}]} , {personName:Smith,animals:[{animalName:cat},{animalName:dog}]} ] 

मैं सर्वर से व्यक्ति सरणी हो रही है। मैं टाइप किए गए व्यक्ति सरणी में सामान्य व्यक्ति सरणी डालना चाहता हूं। इसलिए मैं उपयोग कर सकते हैं

persons[0].Animals[2].Run(); 

मैं सरणी समर्थन के साथ यह जावास्क्रिप्ट के

Object.create(Person,person1); 

लेकिन मैं चाहता हूँ पार ब्राउज़र संस्करण स्थापित

ObjectArray.create(Person,persons); 

या

Object.create(Person[],persons); 
+4

आपका प्रश्न अस्पष्ट है। जावास्क्रिप्ट सरणी टाइप नहीं की जाती हैं। (वैसे नई टाइप-जैसी चीजें हैं जिन्हें टाइप किया गया है लेकिन मूल सरणी नहीं हैं।) – Pointy

+0

वह कोड जो आप कहते हैं कि आप उपयोग करना चाहते हैं, इसका तात्पर्य है कि सर्वर से पुनर्प्राप्त करने वाले व्यक्ति सरणी में ऑब्जेक्ट्स होंगे, उदा। '[{पशु: [...]}, {पशु: [...]}] '- क्या आपका मतलब है? – JMM

+0

मैंने नमूना कोड जोड़ा है। मुझे लगता है कि सवाल अब स्पष्ट है। – ozz

उत्तर

15

जावास्क्रिप्ट में एक वस्तु बनाना समर्थित हो सकता है (और हम सभी को कॉपी करने से बच सकते हैं) ने अपने निर्माता के आह्वान की आवश्यकता है । तो, सबसे पहले आपको सही तर्क खोजने की आवश्यकता होगी, जो हमेशा गुण नहीं हो सकता है। इसके बाद, आप जेएसओएन-पार्स ऑब्जेक्ट से बनाए गए उदाहरणों में सभी सार्वजनिक गुणों को फिर से सौंप सकते हैं।

एक सामान्य समाधान यह होगा कि प्रत्येक कन्स्ट्रक्टर किसी भी ऑब्जेक्ट को स्वीकार करता है जो उदाहरणों (असली उदाहरणों सहित) को देखता है और उन्हें क्लोन करता है। उचित उदाहरण बनाने के लिए आवश्यक सभी आंतरिक तर्क सही जगह पर स्थित होंगे।

Person.fromJSON = function(obj) { 
    // custom code, as appropriate for Person instances 
    // might invoke `new Person` 
    return …; 
}; 

आपका मामला, बहुत सरल है के रूप में आप डॉन ':

या निर्माता अधिक भार से भी बेहतर अपने वर्ग कि उन लोगों से वस्तुओं लेता है और बनाता है उदाहरणों पर एक स्थिर विधि बनाने के लिए हो सकता है टी में कोई तर्क नहीं है और केवल सार्वजनिक गुण हैं।एक वस्तु उदाहरण के लिए {personName:John,animals:[]} बदलने के लिए, इस का उपयोग करें:

var personLiteral = ... // JSON.parse("..."); 
var personInstance = new Person(); 
for (var prop in personLiteral) 
    personInstance[prop] = personLiteral[prop]; 

आप भी इस के लिए Object.extend कार्यक्षमता का उपयोग कर सकते हैं, तो आप एक ही उपलब्ध (उदाहरण के लिए jQuery) होना चाहिए:

var personInstance = $.extend(new Person(), personLiteral); 

Animal उदाहरणों के निर्माण समान काम करता है।

चूंकि जेएसओएन कक्षाओं के बारे में कोई जानकारी नहीं लेता है, तो आपको पहले संरचना को अवश्य जानना चाहिए। आपके मामले में यह हो जाएगा:

var persons = JSON.parse(serverResponse); 
for (var i=0; i<persons.length; i++) { 
    persons[i] = $.extend(new Person, persons[i]); 
    for (var j=0; j<persons[i].animals; j++) { 
     persons[i].animals[j] = $.extend(new Animal, persons[i].animals[j]); 
    } 
} 

Btw, अपने run तरीकों प्रत्येक उदाहरण के बजाय Animal.prototype वस्तु पर जोड़े जाने की संभावना लगती है।

+0

बहुत बहुत धन्यवाद, आपने मुझे समय की पूरी ढेर बचाई! – Tone

1

पहले सब: जावास्क्रिप्ट में आपके पास कक्षाएं नहीं हैं I एन सी ++, जावा या सी #। तो आप वास्तव में एक टाइप की गई सरणी नहीं हो सकता है।

आप जो कर रहे हैं वह मूल रूप से चर के लिए काम करना चाहिए, लेकिन कार्यों के लिए नहीं। तो आपको पहले कार्यों को जोड़ना होगा। एक विचार पाने के लिए निम्नलिखित कोड पर एक नज़र डालें।

<script type="text/javascript"> 

function Person() { 
     var self = this; 

     self.personName=""; 
     self.animals=[]; 
} 

function Animal(){ 
    var self=this; 

    self.animalName=""; 
    self.run=function(meters){ 
     7/... do something 
    } 
} 

var persons = [{personName:"John",animals:[{animalName:"cheetah"},{animalName:"giraffe"}]} , {personName:"Smith",animals:[{animalName:"cat"},{animalName:"dog"}]} ]; 

//use this to assign run-function 
var a = new Animal(); 

//assign run-function to received data 
persons[0].animals[0].run = a.run; 

//now this works 
persons[0].animals[0].run(); 

</script> 
+0

रन फ़ंक्शन असाइन करना इतना दिलचस्प है। मुझे अच्छा लगा। – ozz

1

व्यक्ति वर्ग पर एक स्टेटिक विधि बनाने के बारे में, जो आपके सर्वर प्रतिक्रिया को स्वीकार करेगा और आवश्यक चर बनाएगा।

यह सिर्फ एक विचार है। कृपया देखें कि यह आपकी समस्या में फिट बैठता है या नहीं।

//Static method 
Person.createObjects = function(response) { 
    var persons = []; 
    for (var p = 0; p < response.length; p++) { 
     //Create Person 
     var person = new Person(response[p].personName); 
     //Create Animals 
     for (var a = 0; a < response[p].animals.length; a++) { 
      var animal = new Animal(response[p].animals[a].animalName); 
      //Push this animal into Person 
      person.animals.push (animal); 
     } 
     //Push this person in persons 
     persons.push (person); 
    } 
    //Return persons 
    return persons; 
} 

//Now Create required persons by passing the server response 
var persons = Person.createObjects (response); 
+0

अपने चल रहे चर को ठीक करें। क्या आप 'पी' या' i' का उपयोग करना चाहते हैं? साथ ही, मुझे नहीं लगता कि यह 'व्यक्ति वर्ग' पर एक स्टेटस विधि होनी चाहिए - जब JSON प्रारूप बदलता है तो वर्ग को क्यों बदलें? – Bergi

+0

धन्यवाद बर्गी। मैंने अपने चर को पी में अपडेट किया। और स्थिर विधि के बारे में। हां, यह व्यक्ति वर्ग पर एक स्थिर विधि है। और निश्चित रूप से JSON प्रारूप नहीं बदलेगा। यदि यह बदलता है, तो यह किसी भी मामले में स्वचालित रूप से व्यक्ति ऑब्जेक्ट में परिवर्तित नहीं होगा। इसलिए, संगतता के लिए, जेएसओएन प्रारूप में हमेशा एक ही प्रारूप होना चाहिए। –

2

ऐसा लगता है आपके श्रेणियां होती हैं कि कुछ प्रोटोटाइप तरीकों है और आप सिर्फ अपने वस्तुओं उन तरीकों का उपयोग करने में सक्षम होना चाहते हैं। http://jsfiddle.net/6CrQL/3/

function Person() {} 

Person.prototype.speak = function() { 
    console.log("I am " + this.personName); 
}; 

Person.prototype.runAnimals = function() { 
    this.animals.each(function(animal){ 
     animal.run(); 
    }) 
}; 

function Animal() {} 

Animal.prototype.run = function() { 
    console.log("My Animal " + this.animalName+ " is running"); 
} 

var untypedPersons = [{personName:"John",animals:[{animalName:"cheetah"},{animalName:"giraffe"}]} , {personName:"Smith",animals:[{animalName:"cat"},{animalName:"dog"}]} ]; 

function fromArray(arr, constructor) { 
    return arr.map(function(obj){ 
     var typed = Object.create(constructor.prototype); 
     // Now copy properties from the given object 
     for (var prop in obj) { 
      typed[prop] = obj[prop]; 
     } 
     return typed; 
    }); 
} 

var persons = fromArray(untypedPersons, Person); 
// Attach prototype to each animals list in person 
persons.each(function(person){ 
    person.animals = fromArray(person.animals, Animal); 
}); 

persons.each(function(person){ 
    person.speak(); 
    person.runAnimals(); 
}); 

यह सब बहुत आसान है, तो हर कोई __proto__ संपत्ति http://jsfiddle.net/6CrQL/2/

persons.each(function(person){ 
    person.__proto__ = Person.prototype; 
    person.animals.each(function(animal){ 
    animal.__proto__ = Animal.prototype; 
    }); 
}); 

persons.each(function(person){ 
    person.speak(); 
    person.runAnimals(); 
});​ 
+0

यह 'object.create' के लिए उपयुक्त उपयोग नहीं है, और इस तरह से भी काम नहीं करेगा। – Bergi

+0

@ बर्गि मैंने इसे देखा, इसे एक नए समाधान के साथ अपडेट किया –

+0

'सरोगेट कॉन्स्ट्रक्टर' के लिए अच्छा क्या है, क्या आप सामान्य सामान्य का उपयोग नहीं कर सकते? या यदि आप इसे कॉल करने से बचना चाहते हैं तो 'ऑब्जेक्ट.क्रेट (कंस्ट्रक्टर.प्रोटोटाइप)' का उपयोग करें। – Bergi

संबंधित मुद्दे