2010-07-02 24 views
7

Mam tablicę istniejącego obiektu zdefiniowanego przy pomocy JSON. Obiekty są oczywiście typu Object. Jak powiązać je z niestandardowym typem obiektu, aby nadać mu określoną funkcjonalność?Zmiana typu obiektu w JavaScript

+0

jeśli obiekt ma dodatkowe atrybuty/metody, czego potrzebujesz więcej? czy mógłbyś podać przykład? – mykhal

+0

.. to znaczy, czy masz już zdefiniowane niestandardowe typy obiektów, lub chcesz wiedzieć, jak to zrobić? – mykhal

Odpowiedz

11

Sposób, że będzie działać we wszystkich przeglądarkach jest albo zwiększać każdego elementu w tablicy z właściwości i metod, które mają, lub przekazać obiekt do konstruktora i utworzyć nowy obiekt na podstawie starego obiektu właściwości i metody.

Lub jeśli nie dbają o IE:

var obj = { 
    name : "Jeremy" 
}; 

function CustomType() { 
    this.name = this.name || "someValue"; 
    this.greeting = "Hi"; 
} 

CustomType.prototype.sayHi = function() { 
    alert(this.greeting + ", " + this.name); 
}; 

obj.__proto__ = CustomType.prototype; 
obj.constructor.call(obj); 

obj.sayHi(); 
+1

Dbam o IE, i poszedłem z twoją sugestią, tworząc metodę, która modyfikuje przekazany obiekt i zwraca go z powrotem do rozmówcy. Jestem zbytnio przyzwyczajony do używania "błogosławieństwa" w Perlu i możliwość modyfikowania obiektów w moim kaprysie. – Ray

4

Nie sądzę, że istnieje jakakolwiek zmiana typu obiektu po jego utworzeniu. Na szczęście prawdopodobnie nie musisz zmieniać klasy, swoich obiektów - prawdopodobnie będziesz zadowolony z nadawania obiektom nowych metod i innych funkcji. (Jedyną różnicą jest to, co by się stało, gdyby ZMIENIĆ klasę, a większość ludzi nie zmieniała klas, gdy kod jest uruchomiony.)

Dam wam przykład dla was. Po pierwsze, będę tworzyć prosty obiekt do reprezentowania obiektów JSON masz:

var myobj = new Object() 
myobj.name = "Fred" 

Wtedy będę tworzyć jakąś klasę, że chciałbyś, aby móc przypisać myobj:

function Speaker() { 
    this.speak = function() { 
     window.alert("Hello, " + this.name); 
    } 
} 

ten nowy Speaker klasa ma kilka przydatnych funkcji: można go użyć metody speak() do wyjściowego przydatne informacje:

var s = new Speaker() 
s.name = "Sally" 
s.speak() 

Realizującej która dała m e wiadomość "Witaj, Sally". Niestety, nie chcesz nowego obiektu (np. s) z tą funkcją, chcesz mieć istniejący obiekt (myobj), aby go mieć. Oto jak to zrobić:

myobj.speak = s.speak 

Teraz, kiedy mogę wykonać to:

myobj.speak() 

widzę komunikat "Witam, Fred".

Podsumowując: Utwórz obiekt, który robi to, co chcesz. Skopiuj wszystkie metody (i wszelkie zmienne pomocnicze) do nowego obiektu. Z wyjątkiem niektórych nietypowych zastosowań dziedziczenia, sprawi to, że nowy obiekt będzie działał zgodnie z oczekiwaniami.

2

Jeśli chcesz użyć konkretnej metody, możesz użyć polecenia/zadzwoń.

Lub możesz skopiować metody dla niestandardowego obiektu.

function Object1() { 
    this.aValue = "10"; 
} 

function CustomObject() { 
    this.customValue = "6"; 
} 

function convertToCustom(obj) { 
    var custom = new CustomObject(); 
    for(var key in obj) { 
    custom[key] = obj[key]; 
    } 
    return custom; 
} 

var obj = new Object1(); 
var custom = convertToCustom(obj); 

console.log(custom.customValue); // <- 6 
console.log(custom.aValue);  // <- 10 
0

Jako uzupełnienie odpowiedzi Jeremy'ego, można użyć Object.create zamiast bezpośrednio z gry proto. Będziesz także potrzebować funkcji "rozszerzania".

Tak więc, biorąc przykład Jeremy'ego, można mieć coś takiego:

var obj = { 
name : "Jeremy" 
}; 


function CustomType() { 
} 

CustomType.prototype.init = function(){ 
    this.name = this.name || "someValue"; 
    this.greeting = "Hi"; 
    return this; //let's make it fluent 
} 

CustomType.prototype.sayHi = function() { 
    console.log(this.greeting + ", " + this.name); 
}; 

function extend(obj, props) { 
    for(prop in props) { 
     if(props.hasOwnProperty(prop)) { 
      obj[prop] = props[prop]; 
     } 
    } 
    return obj; //let's make it fluent 
} 

obj = extend(Object.create(CustomType.prototype), obj).init(); 

obj.sayHi(); 
1

Jeśli nie potrzebujesz konstruktora, można zrobić jak:

Object.assign(new CustomType, {});