12

Echa un vistazo a este código. Se trata de un objeto muy simple JavaScript que se implementan utilizando Module Pattern (y se puede ver el ejemplo vivo en this fiddle address)Compatibilidad con obtención de JavaScript en 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); 

Sin embargo, IE8 no soporta JavaScript get y set palabras clave. Puede probarlo y ver MDN.

¿Qué debo hacer para que este script también sea compatible con IE8?

Respuesta

22

¿Qué debo hacer para que este script también sea compatible con IE8?

Cambie por completo. Por ejemplo, en lugar de utilizar las propiedades de descriptor de acceso, utilizar una combinación de propiedades y funciones normales:

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

Alguien sugirió el uso de un objeto DOM en IE y la adición de las propiedades usando Object.defineProperty(). Si bien puede trabajar, lo recomiendo mucho en contra de este enfoque por varias razones, una es que el código que escriba puede no ser compatible en todos los navegadores ejemplo:

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 

Esto es cierto de al menos Chrome. De cualquier manera, es más seguro y fácil escribir código que funcione en todos los navegadores que desee. Cualquier conveniencia que obtenga de poder escribir código para aprovechar getters y setters se ha perdido en el código adicional que escribió específicamente para Internet Explorer 8.

Esto es, por supuesto, además de la reducción en el rendimiento, el hecho de que no podrá usar un bucle for...in en el objeto y la confusión potencial que se produce cuando utiliza una propiedad que pensó que ya había definido pero que ya existía en el objeto DOM.

+0

Quise decir cómo puedo hacer que mi código sea compatible con versiones anteriores. ¿Cuál es la solución para implementar un patrón de módulo en JavaScript que también funciona en IE8 y que tiene propiedades getter? –

+1

@SaeedNeamati Si realmente quieres getters/setters, puedes hacer dos cosas: 1) crear métodos como '.getMyValue' y' .setMyValue', o 2) crear métodos que acepten un valor, o devolverlo si no se da ningún valor (como lo que hace jQuery con algunos métodos: si le da un valor que establece, si no le da un valor, lo obtiene). –

+1

La peor respuesta de todas. No puedo creer que haya recibido tantos votos upvotes. – DontVoteMeDown

8

Puede no (as Andy answered)

La alternativa más cercana sería

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 en http://jsfiddle.net/gaby/WYjqB/2/

+0

IE siempre apesta. Aunque Microsoft tiene muchos buenos productos, realmente odio a Microsoft, solo por su IE. –

+1

@Saeed: realmente, este es un escenario donde no es culpa de Microsoft. Getters y setters son una adición reciente a la especificación ECMA-262. IE 9 admite getters y setters a través de 'Object.defineProperty()'. La implementación que está utilizando (Mozilla) no es estándar y no está garantizada para funcionar en muchos navegadores de todos modos. –

+1

Pero @Gaby, Firefox lo ha soportado desde la versión 2.0, Chrome desde la versión 1, Safari desde la versión 3.5 y Opera desde la versión 9.5. Entonces, ¿cómo es eso, que IE8 no puede soportar tal cosa? –

4

comprobarlo en http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/

El futuro, y el estándar ECMAScript de manera extendida, de extender objetos en todo tipo de formas es a través de Object.defineProperty. Así es como Internet Explorer eligió implementar getters y setters, pero es desafortunadamente hasta ahora solo está disponible en Internet Explorer 8, y no en en cualquier otro navegador web. Además, IE 8 solo lo admite en nodos DOM, pero las versiones futuras de están planificadas para admitirlo en objetos de JavaScript como .

Puede encontrar los casos de prueba en el mismo sitio en 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"; 

Resultado:

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

Corregido el resultado. –

5

IE8 es compatible con captadores y definidores de nodos DOM, por lo que si realmente quiere tener getters y setters, puede hacer esto:

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); 

Tenga en cuenta que esto le da un impacto de rendimiento algo significativo, por lo que no utilizaría esta técnica si necesita crear miles de objetos como este. Pero si no te preocupa el rendimiento de este objeto en particular, te matará. Y si no le importa el rendimiento ie8, y solo quiere que funcione, use esta técnica solo para ie8 y está de oro:)

+1

Hay varios problemas con este enfoque que lo hacen demasiado complicado y que realmente no lo vale. Por ejemplo, la herencia prototípica sale de la ventana, los problemas de rendimiento de creación de objetos que mencionas, posibles colisiones de nombres, etc. Está lejos de ser "dorado". –

+2

Si bien no es una solución dorada (la gran posibilidad de eso al usar IE), de hecho responde la pregunta ... –

+2

Gracias. Todo lo que necesitaba era una clase compacta y simple para almacenar/recuperar valores durante la sesión. Esto me facilitó declarar y usar propiedades cuando fue necesario. – gouderadrian

Cuestiones relacionadas