[英]What did Douglas Crockford mean by 'constructed in a different window or frame'?
道格拉斯· is_array()
Douglas Crockford)在編寫is_array()
測試時會說它無法識別在不同窗口或框架中構建的數組,這意味着什么?
var is_array = function (value) {
return value &&
typeof value === 'object' &&
value.constructor === Array;
為什么以下工作跨越窗口和框架?
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
例如,如果你有一個iframe
,它有自己的window
,那里構造的任何Array
都將失敗另一個window
的測試。 那是因為最后一個條件,它假定當前window
的Array
,它是一個不同的對象。
var isArray = document.querySelector("iframe").contentWindow.Array === Array;
// false (wrong, it *is* an array)
jsFiddle 。
后者通過知道typeof
總是說Array
是一個"object"
,以及尋找Array
上存在的屬性來工作。
但是,通過構造一個看起來像數組的對象,它可能會被欺騙。
var isArray = is_array(Object.create({length: 0, splice: function() {}}));
// true (wrong, it *isn't* an array)
jsFiddle 。
另一種方法是在其上調用Object
的toString()
方法,它將返回內部類。
var isArray = ({}).toString.call(value) == "[object Array]";
// true (correct, it's an array)
jsFiddle 。
這在多window
環境中工作,不能被欺騙 (盡管有更多的開銷以這種方式檢查它,但永遠不會成為瓶頸)。
我認為亞歷克斯的解決方案比克羅克福德更好。 這個答案是指出克羅克福德解決方案的缺陷。
看到這個:
我故意創造了一個有缺陷的對象。
function Stupid(){}
Stupid.prototype.length = 0;
Stupid.prototype.splice = function () {}
var stupid = new Stupid();
is_array(stupid);
// true
顯然,如果你看到有人設定原型的長度,你就有權將頭撞到牆上。
但這是有效的:
function Mediocre(){
Object.defineProperty(this, 'length', {
get: function () { return 42; },
enumerable: false
});
}
Mediocre.prototype.splice = function () {}
var m = new Mediocre();
is_array(m);
// true
所以,你不應該試圖超越常規/常用方法,因為你無法猜測其他開發人員會做什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.