We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
先看MDN:Array.isArray()
能准确区分数组和类数组对象!
接下来是翻译:
JavaScript的 typeof 操作符有着令人困惑的表现行为:typeof null === "object",而 typeof null !== "null"。这个错误会让人震惊,但我们基本上已经习惯了。可能更重要的是,有一个故障安全的解决方法:简单直接的用 === (全等)比较,例如 v === null 来进行判断。
typeof
typeof null === "object"
typeof null !== "null"
===
v === null
typeof null === "object" 可能是最常见的类型校验错误,不过还存在其它的类型校验错误。一个不太普遍但同样令人困惑的问题是 如何确定对象是否为数组。你可能会有个简单的解决方案:
if (o instanceof Array) { // 太糟糕了 }
在某些情况下,上面代码运行完美。但是如果存在 多个全局变量 就会出现问题。
ECMAScript规范描述了当执行一串代码时调用的环境和机制。语言构造的语法和基本语义当然很重要,但是如果没有ECMAScript中的内置方法和对象编码,就不能很好工作。这些方法和对象被全局对象使用,这里就是奇怪事情的发生地。ECMAScript 3 环境隐式假定存在单个全局变量(或者,也许是每个独立部分都有自己的环境,彼此之间没有相互作用)并且没有解决多个全局变量的想法。
但是,多个全局变量是浏览器的基础;每个 window 对象是该页面包含或引用的脚本的全局对象。那么在不同 window 中的数组呢?
window
当两个页面都增加 Array.prototype 时,将两个 window 的数组作为同一 Array 构造函数的实例,共享相同 Array.prototype 的 变化风险 非常大(更不用说当一个页面为恶意页面时的安全问题!),因此每个窗口中的 Array 和 Array.prototype 必须不同。所以,仅当 o 是由该页面原始 Array 构造器创建的数组(或者使用该页面数组字面量创建),o instanceof Array 才会运行正确。
Array.prototype
Array
o
o instanceof Array
是否还有其他可以确定值是数组的方法?
o.constructor === Array
instanceof
constructor
push
concat
length
Object.prototype.toString.call(o) === "[object Array]"
Object.prototype.toString
Function.prototype.call
由于这些原因,ES5定义了 Array.isArray 方法来完全解决该问题。
Array.isArray
Array.isArray(Array.prototype); // true function test(fun, expect) { if (fun() !== expect) alert("FAIL: " + fun); } test(function() { return Array.isArray([]); }, true); test(function() { return Array.isArray(new Array); }, true); test(function() { return Array.isArray(); }, false); test(function() { return Array.isArray({ constructor: Array }); }, false); test(function() { return Array.isArray( { push: Array.prototype.push, concat: Array.prototype.concat } ); }, false); test(function() { return Array.isArray(17); }, false); Object.prototype.toString = function() { return "[object Array]"; }; test(function() { return Array.isArray({}); }, false); test(function() { return Array.isArray({ __proto__: Array.prototype }); }, false); test(function() { return Array.isArray({ length: 0 }); }, false); var w = window.open("about:blank"); w.onload = function() { test(function() { return Array.isArray(arguments); }, false); test(function() { return Array.isArray(new w.Array); }, true); };
The text was updated successfully, but these errors were encountered:
No branches or pull requests
严格判定JavaScript对象是否为数组
先看MDN:Array.isArray()
接下来是翻译:
JavaScript中的类型校验问题
JavaScript的
typeof
操作符有着令人困惑的表现行为:typeof null === "object"
,而typeof null !== "null"
。这个错误会让人震惊,但我们基本上已经习惯了。可能更重要的是,有一个故障安全的解决方法:简单直接的用===
(全等)比较,例如v === null
来进行判断。确定值是否为数组
typeof null === "object"
可能是最常见的类型校验错误,不过还存在其它的类型校验错误。一个不太普遍但同样令人困惑的问题是 如何确定对象是否为数组。你可能会有个简单的解决方案:在某些情况下,上面代码运行完美。但是如果存在 多个全局变量 就会出现问题。
ECMAScript规范描述了当执行一串代码时调用的环境和机制。语言构造的语法和基本语义当然很重要,但是如果没有ECMAScript中的内置方法和对象编码,就不能很好工作。这些方法和对象被全局对象使用,这里就是奇怪事情的发生地。ECMAScript 3 环境隐式假定存在单个全局变量(或者,也许是每个独立部分都有自己的环境,彼此之间没有相互作用)并且没有解决多个全局变量的想法。
但是,多个全局变量是浏览器的基础;每个
window
对象是该页面包含或引用的脚本的全局对象。那么在不同window
中的数组呢?当两个页面都增加
Array.prototype
时,将两个window
的数组作为同一Array
构造函数的实例,共享相同Array.prototype
的 变化风险 非常大(更不用说当一个页面为恶意页面时的安全问题!),因此每个窗口中的Array
和Array.prototype
必须不同。所以,仅当o
是由该页面原始Array
构造器创建的数组(或者使用该页面数组字面量创建),o instanceof Array
才会运行正确。是否还有其他可以确定值是数组的方法?
o.constructor === Array
是一种方法,但和instanceof
有相同的问题。constructor
检查,您可以检查其他数组方法(例如push
或concat
),或者检查length
属性,但是非数组对象也可以有这些同名属性。Object.prototype.toString.call(o) === "[object Array]"
,但是依赖于Object.prototype.toString
和Function.prototype.call
未被改变。来到 Array.isArray
由于这些原因,ES5定义了
Array.isArray
方法来完全解决该问题。规范
The text was updated successfully, but these errors were encountered: