12

Sprawdź ten kod. Jest to bardzo prosty obiekt JavaScript, który jest realizowany za pomocą Module Pattern (i można zobaczyć na żywo na przykład this fiddle address)Obsługa JavaScriptu w IE8

var human = function() { 
    var _firstName = ''; 
    var _lastName = '' 
    return { 
     get firstName() { 
      return _firstName; 
     }, get lastName() { 
      return _lastName; 
     }, set firstName(name) { 
      _firstName = name; 
     }, set lastName(name) { 
      _lastName = name; 
     }, get fullName() { 
      return _firstName + ' ' + _lastName; 
     } 
    } 
}(); 
human.firstName = 'Saeed'; 
human.lastName = 'Neamati'; 
alert(human.fullName); 

Jednak IE8 nie obsługuje JavaScript get i set kluczowych. Możesz je przetestować i zobaczyć MDN.

Co należy zrobić, aby ten skrypt był zgodny z IE8?

Odpowiedz

22

Co należy zrobić, aby ten skrypt był zgodny z IE8?

Zmień go całkowicie. Na przykład, zamiast korzystania z właściwości dostępowe, użyć kombinacji normalnych właściwości i funkcje:

human.firstName = 'Saeed'; 
human.lastName = 'Neamati'; 
alert(human.getFullName()); 

Ktoś zasugerował pomocą obiektu DOM w IE i dodawanie właściwości używając Object.defineProperty(). Chociaż może to działać, bardzo polecam przeciwko takiemu podejściu z kilku powodów, przykładowo jest, że piszesz kod może nie być kompatybilna z wszystkimi przeglądarkami:

var human = document.createElement('div'); 
Object.defineProperty(human, 'firstName', { ... }); 
Object.defineProperty(human, 'lastName', { ... }); 
Object.defineProperty(human, 'children', { value: 2 }); 

alert(human.children); 
//-> "[object HTMLCollection]", not 2 

to prawda przynajmniej z Chrome. W każdym razie bezpieczniej i łatwiej jest pisać kod, który działa we wszystkich przeglądarkach, które chcesz obsługiwać. Dowolna wygoda, jaką można uzyskać dzięki możliwości pisania kodu w celu skorzystania z modułów pobierających i ustawiających, została utracona przez dodatkowy kod napisany specjalnie w programie Internet Explorer 8.

Jest to, oczywiście, oprócz zmniejszenia wydajności, fakt, że nie będziesz w stanie użyć pętli for...in na obiekcie i potencjalne zamieszanie wynikające z użycia właściwości, którą myślałeś, że zdefiniowałeś, ale która wcześniej istniała w obiekcie DOM.

+0

Chodzi mi o to, jak mogę uczynić mój kod kompatybilnym wstecz. Jakie jest rozwiązanie do implementacji wzorca modułu w JavaScript, który działa również w IE8 i który ma właściwości gettera? –

+1

@SaeedNeamati Jeśli naprawdę chcesz pobrać/ustawiasz, możesz zrobić dwie rzeczy: 1) tworzyć metody takie jak '.getMyValue' i' .setMyValue' lub 2) tworzyć metody, które akceptują wartość, lub zwracać je, jeśli żadna wartość nie jest podana (jak to, co robi jQuery z niektórymi metodami - jeśli podasz wartość, którą ustawisz, jeśli nie podasz wartości, którą otrzymasz). –

+1

Najgorsza odpowiedź w historii. Nie mogę uwierzyć, że zyskały one tak dużo awansów. – DontVoteMeDown

8

Nie można (as Andy answered)

Najbliżej alternatywą byłoby

var human = function() { 
    var _firstName = ''; 
    var _lastName = ''; 

    return { 
     firstName: function() { 
      if (arguments.length === 1) { 
       _firstName = arguments[0]; 
      } 
      else { 
       return _firstName; 
      } 
     }, 
     lastName: function() { 
      if (arguments.length === 1) { 
       _lastName = arguments[0]; 
      } 
      else { 
       return _lastName; 
      } 
     }, 
     fullName: function() { 
      return _firstName + ' ' + _lastName; 
     } 
    }; 
}(); 

human.firstName('Saeed'); 
human.lastName('Neamati'); 

alert(human.fullName()); 

Demo na http://jsfiddle.net/gaby/WYjqB/2/

+0

IE zawsze jest do bani. Chociaż Microsoft ma wiele dobrych produktów, ale naprawdę nienawidzę Microsoftu, tylko ze względu na jego IE. –

+1

@Seed: tak, to jest jeden scenariusz, w którym to nie jest wina Microsoftu. Przeciągacze i setery są ostatnim dodatkiem do specyfikacji ECMA-262. IE 9 obsługuje obiekty pobierające i ustawiające za pomocą 'Object.defineProperty()'. Implementacja, z której korzystasz (Mozilla) jest niestandardowa i nie gwarantuje pracy w wielu przeglądarkach. –

+1

Ale @Gaby, Firefox obsługuje to od wersji 2.0, Chrome od wersji 1, Safari od wersji 3.5 i Opera od wersji 9.5. Jak to jest, że IE8 nie może tego poprzeć? –

4

Sprawdź to na http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/

przyszłości i standard ECMAScript sposób uporządkowany, rozszerzania obiektów w na różne sposoby jest przez Object.defineProperty. W ten sposób Internet Explorer zdecydował się na implementację modułów pobierających i ustawiających, ale jest to niestety do tej pory dostępne tylko w przeglądarce Internet Explorer 8, a nie w żadnej innej przeglądarce internetowej. Ponadto IE 8 obsługuje go tylko w węzłach DOM, ale przyszłe wersje są planowane do obsługi w obiektach JavaScript jako .

można znaleźć przypadki testowe na tym samym miejscu w http://robertnyman.com/javascript/javascript-getters-setters.html#object-defineproperty

Object.defineProperty(document.body, "description", { 
    get : function() { 
     return this.desc; 
    }, 
    set : function (val) { 
     this.desc = val; 
    } 
}); 
document.body.description = "Content container"; 

Wynik:

document.body.description = "Content container" 
+0

Poprawiono wynik. –

5

IE8 obsługuje pobierające i ustawiające na węzłach DOM, więc jeśli naprawdę chcesz mieć pobierające i ustawiające, możesz to zrobić:

var objectForIe8 = $("<div></div>")[0];  
Object.defineProperty(objectForIe8, "querySelector", { 
    get: function() { 
     return this.name; 
    }, 
    set: function(val) { 
     this.name = val+", buddy"; 
    } 
}); 
// notice you can overwrite dom properties when you want to use that property name 
objectForIe8.querySelector = "I'm not your guy"; 

alert(objectForIe8.querySelector); 

Zauważ, że daje to dość znaczący efekt, więc nie użyłbym tej techniki, jeśli potrzebujesz stworzyć tysiące takich obiektów. Ale jeśli nie martwisz się o wydajność tego konkretnego obiektu, to cię odpędzi. A jeśli nie dbasz o wydajność ie8 i chcesz, żeby działała, użyj tej techniki tylko dla ie8 i jesteś złoty:)

+1

Jest kilka problemów z tym podejściem, które sprawiają, że jest zbyt skomplikowany i naprawdę nie warto. Na przykład dziedziczenie prototypowe wychodzi z okna, problemy z wydajnością tworzenia obiektów, o których wspominasz, możliwe kolizje nazw i tak dalej. To daleko od "złotego". –

+2

Chociaż nie jest to złote rozwiązanie (jest to duża szansa podczas używania IE), w rzeczywistości odpowiada na pytanie ... –

+2

Dzięki. Wszystko, czego potrzebowałem, to zwarta i prosta klasa do przechowywania/pobierania wartości na czas trwania sesji. Ułatwiło mi to deklarowanie i używanie właściwości w razie potrzeby. – gouderadrian