Si lo entiendo correctamente, todos y cada uno de los objetos de Javascript heredan del prototipo de Objeto, lo que significa que todos y cada uno de los objetos de Javascript tienen acceso a la función hasOwnProperty a través de su cadena de prototipos.
Mientras leía el código fuente de require.js, me topé con esta función:
function hasProp(obj, prop) {
return hasOwn.call(obj, prop);
}
hasOwn
es una referencia a Object.prototype.hasOwnProperty
. ¿Existe alguna diferencia práctica en escribir esta función como
function hasProp(obj, prop) {
return obj.hasOwnProperty(prop);
}
Y ya que estamos en eso, ¿por qué definimos esta función? ¿Es solo una cuestión de accesos directos y almacenamiento en caché local del acceso a la propiedad para obtener (leves) ganancias de rendimiento, o me falta algún caso en el que hasOwnProperty podría usarse en objetos que no tienen este método?
const hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
Puede parecer que se parten los pelos, pero hay una diferencia entre javascript (el término genérico para las implementaciones de ECMAScript) y ECMAScript (el lenguaje utilizado para las implementaciones de javascript). Es ECMAScript el que define un esquema de herencia, no javascript, por lo que solo los objetos ECMAScript nativos necesitan implementar ese esquema de herencia.
Un programa javascript en ejecución consta de al menos los objetos ECMAScript integrados (Objeto, Función, Número, etc.) y probablemente algunos objetos nativos (por ejemplo, funciones). También puede tener algunos objetos de host (como objetos DOM en un navegador u otros objetos en otros entornos de host).
Si bien los objetos nativos e integrados deben implementar el esquema de herencia definido en ECMA-262, los objetos host no lo hacen. Por lo tanto, no todos los objetos en un entorno javascript deben heredar de Object.prototype . Por ejemplo, los objetos host en IE implementados como objetos ActiveX arrojarán errores si se tratan como objetos nativos (de ahí la razón por la que try..catch se usa para inicializar objetos MS XMLHttpRequest). Algunos objetos DOM (como NodeLists en IE en modo peculiar) si se pasan a métodos Array arrojarán errores, los objetos DOM en IE 8 y versiones inferiores no tienen un esquema de herencia similar a ECMAScript, y así sucesivamente.
Por lo tanto, no se debe asumir que todos los objetos en un entorno javascript heredan de Object.prototype.
Lo cual no es cierto para ciertos objetos de host en IE en modo peculiar (e IE 8 e inferior siempre) al menos.
Dado lo anterior, vale la pena reflexionar sobre por qué un objeto podría tener su propio método hasOwnProperty y la conveniencia de llamar a otro método hasOwnProperty en su lugar sin probar primero si es una buena idea o no.
Editar
Sospecho que la razón para usarlo
Object.prototype.hasOwnProperty.call
es que en algunos navegadores, los objetos de host no tienen un método hasOwnProperty , usar call y el método incorporado es una alternativa. Sin embargo, hacerlo de forma genérica no parece una buena idea por las razones mencionadas anteriormente.En lo que respecta a los objetos del host, el operador in se puede utilizar para probar las propiedades en general, p. Ej.
Una alternativa (probada en IE6 y otros):
De esa manera, solo llama específicamente a la propiedad hasOwnProperty incorporada donde el objeto no la tiene (heredada o no).
Sin embargo, si un objeto no tiene un
hasOwnProperty
método, probablemente sea tan adecuado usar el operador in , ya que el objeto probablemente no tenga un esquema de herencia y todas las propiedades estén en el objeto (eso es solo una suposición), por ejemplo, el El operador in es una forma común (y aparentemente exitosa) de probar el soporte de objetos DOM para propiedades.fuente
in
no realiza unahasOwnProperty()
búsqueda, sospecho que la propiedad que estaba buscando existía en la cadena de prototipos.hasOwnProperty
directamente al objeto resultante, porque un cliente malintencionado podría envíe un valor JSON como{"hasOwnProperty": 1}
y haga que el servidor se bloquee.Si existe la posibilidad de que un objeto tenga una propiedad con este nombre, es necesario utilizar una propiedad hasOwnProperty externa para obtener resultados correctos:
Puede copiar y pegar los siguientes fragmentos de código en la consola de su navegador para comprender mejor
Siempre devuelve falso
Utilice hasOwnProperty de otro objeto y llámelo con este conjunto para foo
También es posible utilizar la propiedad hasOwnProperty del prototipo de objeto para este propósito
fuente
hasOwnProperty
devolucionestrue
.La información proporcionada en ambas respuestas existentes es acertada. Sin embargo, el uso de:
se menciona varias veces. Cabe señalar que las
hasOwnProperty
implementaciones devolverán verdadero solo si la propiedad está contenida directamente en el objeto que se está probando.El
in
operador también inspeccionará a lo largo de la cadena del prototipo.Esto significa que las propiedades de la instancia devolverán verdadero cuando se pasen a
hasOwnProperty
where, ya que las propiedades del prototipo devolverán falso.Al usar el
in
operador, las propiedades de la instancia y del prototipo devolverán verdadero.fuente