javascript - Array.isArray() 方法如何检查数组?

标签 javascript prototype prototypal-inheritance

范围:我一直在学习 java 脚本中的原型(prototype)继承,并在我的网络浏览器中尝试了以下代码。在执行以下代码时,我发现了一些非常有趣的东西。

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

问题:我创建了一个数组并打印了它的原型(prototype),然后调用数组的 find 方法并使用 Array.isArray() 方法检查它是否是一个数组。然后我将 y 的原型(prototype)分配给 rabbit 对象

当我检查它是否仍然是一个数组时,我得到了 true,但是当调用 find 方法时我得到一个错误并且在检查原型(prototype)时没有数组的函数。

那么Array.isArray()方法返回true的依据是什么。

输出:

[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

最佳答案

取决于你问的是谁。


ECMAScript 2021 Language standard说:

7.2.2 IsArray ( argument )

The abstract operation IsArray takes argument argument. It performs the following steps when called:

  1. If Type(argument) is not Object, return false.
  2. If argument is an Array exotic object, return true.
  3. If argument is a Proxy exotic object, then
    a. If argument.[[ProxyHandler]] is null, throw a TypeError exception.
    b. Let target be argument.[[ProxyTarget]].
    c. Return ? IsArray(target).
  4. Return false.

(针对此平台重新格式化)

了解内置 Javascript 对象具有引擎内部的表示可能会有所帮助。这就是上面的伪代码所指的。 Javascript 无法访问伪代码引用的某些内容,但引擎可以。


另一方面,Javascript 库通常根据库的历史、它们想要的健壮性或它们的目标是什么来做几件事中的一个。由于他们无法访问引擎内部,因此这些猜测在现实世界中很可能是正确的:

  • 现代库遵循 Array.isArray()
  • Polyfill 通常使用 Object.prototype.toString.call(obj) === '[object Array]'(我相信由 Mozilla 标准化)
  • 鸭子打字:Boolean(obj) && obj.length != null && typeof obj.push === 'function'
  • 基于构造函数:Boolean(obj) && obj.constructor === Array
  • instanceof 基于:obj instanceof Array

这不是一个详尽的 list 。

关于javascript - Array.isArray() 方法如何检查数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72412420/

相关文章:

javascript - 为什么我们使用 "prototype"属性向构造函数实例添加方法?

javascript - 发送后无法设置 header 。调用 create(data,cb) 时

javascript - Cheerio 从 href 中的 json 获取图像

javascript - 如何禁用 CKEditor 4.x 拼写检查器

javascript - 通过将它们的方法包装在一起,Typescript 类对象的性能是否会变慢?

程序运行时Javascript代码显示未定义

javascript - 两个图像 - 如果单击图像是否显示其他图像?

Javascript 正则表达式原型(prototype)

javascript - Javascript原型(prototype)继承和对象属性阴影

javascript - 向 es6 子类添加方法