2016-03-29 9 views
0

BeschreibungjQuery erweitern Kopieren im Vergleich zu früheren Schließungen

In meinem Beispiel Ich versuche, eine einfache Klasse zu definieren (so genannten Car) mit einem private Elemente und ein public Getter. Ich habe auch ein anderes Objekt, das ich einer Instanz meiner Klasse zuordnen möchte. Ich verwende jQuery.extend(), um dies zu erreichen und es funktioniert gut, außer wenn das Mitglied privat ist (nicht daran gebunden). Ich vermute, das liegt daran, dass die Getter-Funktion über die zum Zeitpunkt der Objekterstellung definierten Werte geschlossen hat.

Ich möchte immer noch in der Lage sein, die Funktion über das Mitglied nach der .extend() wieder zu schließen, so wird es den neuen Wert widerspiegeln, kann mir jemand helfen, dies zu erreichen?

Ich habe auch versucht, die zu einem Objekt in {} Referenz übergaben erstreckt, und dann unter Verwendung dieses leeres Objekt als Ziel wie folgt:

function mapToObject(template, json) { 
    var b = $.extend(true,{}, template); 
    return $.extend(true, b, json); 
} 

auch diese nicht die vorherige Schließung brechen.

Mein Code:

// simple class with private member 
function Car() { 
    var noOfWheels = 2; 
    this.honk = function() { 
    alert(noOfWheels); 
    } 
} 
// method which converts JSON object to a more typed class object 
function mapToObject(template, json) { 
    return $.extend(true, template, json); 
} 

// sample Object , in reality coming from AJAX response 
var t = { 
    noOfWheels: 5 
}; 
// i want to map t to an instance of Car 
var r = mapToObject(new Car, t);// closing here during new Car, i think 
r.honk(); // this alerts 2 not 5 because of closure! 

Fiddle:

https://jsfiddle.net/sajjansarkar/samj3pjq/2/

[EDIT] Meine Lösung basiert auf DrFlink Antwort:

// one class 
function Car(options) { 
    var settings = $.extend({ 
    noOfWheels: 2 
    }, options || {}); 
    this.honk = function() { 
    alert(settings.noOfWheels); 
    } 
} 
// another class 
function Lemon(options) { 
    var settings = $.extend({ 
    color: null 
    }, options || {}); 
    this.getColor = function() { 
    alert(settings.color); 
    } 
} 
// function to map any json to a template class instance 
function ObjectMapperFactory(template, json) { 
    if (!jQuery.isArray(json)) { 
    return new template(json); 
    } else { 
    var returnArray = []; 
    $(json).each(function() { 
     returnArray.push(new template(this)) 
    }); 
    return returnArray; 
    } 
} 

//test 1 
var carJSON = { 
    noOfWheels: 5 
}; 
var c = ObjectMapperFactory(Car, carJSON); 
c.honk(); 
//test2 -different class and also testing array 
var lemonJSON = [{ 
    color: "yeller" 
},{ 
    color: "red" 
}]; 

var c = ObjectMapperFactory(Lemon, lemonJSON); 
c[0].getColor(); 
c[1].getColor(); 

FIDDLE AKTUALISIERT:

https://jsfiddle.net/sajjansarkar/samj3pjq/3/

Antwort

1

Warum wollen Sie es auf diese Weise zu tun? Vielleicht wird dies einfacher sein:

// simple class with private member 
 
var Car = function(options) { 
 
    var settings = $.extend({ 
 
    noOfWheels: 2 
 
    }, options || {}); 
 

 
    // Public method - can be called from client code 
 
    this.honk = function(){ 
 
    alert(settings.noOfWheels); 
 
    }; 
 

 
    // Private method - can only be called from within this object 
 
    var myPrivateMethod = function(){ 
 
    alert('This is private!'); 
 
    }; 
 
}; 
 

 
// sample Object 
 
var t = { 
 
    noOfWheels: 4 
 
}; 
 

 
var I = new Car(t); 
 
var J = new Car({ 
 
    noOfWheels: 6 
 
}); 
 

 
I.honk(); 
 
J.honk();

+0

es Ihnen danken! während ich es vorgezogen habe, den Konstruktor meiner Klasse nicht zu ändern, macht es die Dinge einfacher. In meinem Fall musste ich die Funktion generisch machen und jede Instanz der Klasse behandeln, so dass ich den neuen Car() - Konstruktor nicht direkt verwenden konnte, aber ich habe Ihren Vorschlag verwendet, danke! –

Verwandte Themen