簡體   English   中英

道格拉斯·克羅克福德的意思是“在不同的窗戶或框架中建造”?

[英]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的測試。 那是因為最后一個條件,它假定當前windowArray ,它是一個不同的對象。

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

另一種方法是在其上調用ObjecttoString()方法,它將返回內部類。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM