Scope: I have been learning prototype inheritance
in java script and I tried the following code in my web browser. I found something really interesting while executing the following code.
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));
Question: I have created a array and printed its prototype and then called the find method of array and check whether it's an array using Array.isArray()
method. Then I have assigned the prototype of y to rabbit object
.
When I checked if it is still an array, I got true, but when calling the find method I get an error and on checking the prototype there was no functions of an array.
Then on what basis does the Array.isArray()
method returns true.
Output:
[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:11
Depends on who you ask.
The ECMAScript 2021 Language standard says:
7.2.2 IsArray ( argument )
The abstract operation
IsArray
takesargument
argument. It performs the following steps when called:
- If
Type(argument)
is notObject
, returnfalse
.- If argument is an
Array
exotic object, returntrue
.- If argument is a
Proxy
exotic object, then
a. Ifargument.[[ProxyHandler]]
isnull
, throw aTypeError
exception.
b. Lettarget
beargument.[[ProxyTarget]]
.
c. Return? IsArray(target)
.- Return
false
.
(Reformatted for this platform)
It may help to know that built-in Javascript objects have a representation that is internal to the engine. This is what the above pseudo-code is referring to. Javascript doesn't have access to some of the things that the pseudo-code refers to but the engine does.
Javascript libraries, on the other hand, typically do one of several things depending on how old the library is, how robust they want to be, or what their goal is. Since they don't have access to the engine internals, these are guesses with a high probability of being correct in the real world:
Array.isArray()
Object.prototype.toString.call(obj) === '[object Array]'
(standardized by Mozilla, I believe)Boolean(obj) && obj.length != null && typeof obj.push === 'function'
Boolean(obj) && obj.constructor === Array
instanceof
based: obj instanceof Array
This is not an exhaustive list.