Alcance: he estado aprendiendo prototype inheritance en java script y probé el siguiente código en mi navegador web. Encontré algo realmente interesante mientras ejecutaba el siguiente código.
let animal = { eats: true }; let rabbit = { jumps: true }; const p=Object.create(rabbit) rabbit.__proto__ = animal let y=new Array(2,3) console.log(Object.getPrototypeOf(y)) var val=y.find((b)=>(b==2)); console.log(val); console.log(Array.isArray(y)) y.__proto__=rabbit console.log(Array.isArray(y)) console.log(Object.getPrototypeOf(y)) var ccl=y.find((b)=>(b==2)); Pregunta : Creé una matriz e imprimí su prototipo y luego llamé al método de búsqueda de la matriz y compruebo si es una matriz usando el método Array.isArray() . Luego he asignado el prototipo de y al rabbit object .
Cuando verifiqué si todavía es una matriz, obtuve la verdad, pero al llamar al método de búsqueda, aparece un error y al verificar el prototipo no había funciones de una matriz.
Entonces, ¿sobre qué base el método Array.isArray() devuelve verdadero?
Salida :
[constructor: ƒ, concat: ƒ, copyWithin: ƒ, fill: ƒ, find: ƒ, …]at: ƒ at()concat: ƒ concat()constructor: ƒ Array()copyWithin: ƒ copyWithin()entries: ƒ entries()every: ƒ every()fill: ƒ fill()filter: ƒ filter()find: ƒ find()findIndex: ƒ findIndex()findLast: ƒ findLast()findLastIndex: ƒ findLastIndex()flat: ƒ flat()flatMap: ƒ flatMap()forEach: ƒ forEach()includes: ƒ includes()indexOf: ƒ indexOf()join: ƒ join()keys: ƒ keys()lastIndexOf: ƒ lastIndexOf()length: 0map: ƒ map()pop: ƒ pop()push: ƒ push()reduce: ƒ reduce()reduceRight: ƒ reduceRight()reverse: ƒ reverse()shift: ƒ shift()slice: ƒ slice()some: ƒ some()sort: ƒ sort()splice: ƒ splice()toLocaleString: ƒ toLocaleString()toString: ƒ toString()unshift: ƒ unshift()values: ƒ values()Symbol(Symbol.iterator): ƒ values()Symbol(Symbol.unscopables): {copyWithin: true, entries: true, fill: true, find: true, findIndex: true, …}[[Prototype]]: Object 2 true true {jumps: true}jumps: true[[Prototype]]: Objecteats: true[[Prototype]]: Objectconstructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()__proto__: (...)get __proto__: ƒ __proto__()set __proto__: ƒ __proto__() Uncaught TypeError: y.find is not a function at <anonymous>:17:11Depende de a quién le preguntes.
El estándar de lenguaje ECMAScript 2021 dice:
7.2.2 IsArray (argumento)
La operación abstracta
IsArraytomaargumentargumento. Realiza los siguientes pasos cuando se le llama:
- Si
Type(argument)no esObject, devuelvefalse.- Si el argumento es un objeto exótico
Array, devuelvetrue.- Si el argumento es un objeto exótico
Proxy, entonces
una. Siargument.[[ProxyHandler]]esnull, lanza una excepciónTypeError.
b. Deje quetargetsea elargument.[[ProxyTarget]].
C. ¿Regresar? IsArray(target).- Devuelve
false.
(Reformateado para esta plataforma)
Puede ser útil saber que los objetos de Javascript incorporados tienen una representación que es interna al motor. Esto es a lo que se refiere el pseudocódigo anterior. Javascript no tiene acceso a algunas de las cosas a las que se refiere el pseudocódigo, pero el motor sí.
Las bibliotecas de Javascript, por otro lado, generalmente hacen una de varias cosas según la antigüedad de la biblioteca, qué tan robustas quieren ser o cuál es su objetivo. Dado que no tienen acceso a las partes internas del motor, estas son conjeturas con una alta probabilidad de ser correctas en el mundo real:
Array.isArray()Object.prototype.toString.call(obj) === '[object Array]' (estandarizado por Mozilla, creo)Boolean(obj) && obj.length != null && typeof obj.push === 'function'Boolean(obj) && obj.constructor === Arrayinstanceof : obj instanceof ArrayEsta no es una lista exhaustiva.
isArray toma el valor del argumento y lo evalúa en función del valor.y let y=new Array(2,3) , el objeto prototipo de y es Array , que tiene el método find , por lo que podemos ejecutar el método find en y .y.__proto__ = rabbit , el objeto prototipo de y se cambia a rabbit , que no tiene el método de find y el valor de y sigue siendo [2,3]find , por lo que recibimos un error. El valor y no cambia debido al cambio del objeto prototipo, por lo que Array.isArray(y) devuelve verdadero.y después de cada paso y expandiendo el objeto [[Prototype]]