2010-12-22 21 views
4

我遇到一個js函數片斷,列表如下如何理解在JavaScript中是否(在{}中的名稱)?

each = function(obj, fun) { 
    if (typeof fun != "function") { 
     return obj 
    } 
    if (obj) { 
     var return_value; 
     if (obj.length === undefined) { 
      for (var name in obj) { 
       if (name in {}) { // how to undertand this line, what's purpose? 
        continue 
       } 
       return_value = fun.call(obj[name], obj[name], name); 
       if (return_value == "break") { 
        break 
       } 
      } 
     } else { 
      for (var i = 0, 
      length = obj.length; i < length; i++) { 
       return_value = fun.call(obj[i], obj[i], i); 
       if (return_value == "break") { 
        break 
       } 
      } 
     } 
    } 
    return obj 
}; 

謝謝您的回答:)

+1

這是一個很好的問題。爲什麼這是downvoted? – 2010-12-22 12:47:54

回答

4

它正在做的是看到該屬性名稱是否存在於空白對象中。因此,例如,它會過濾出toString(在不是關於toStringin; IE是bug的實現方面)。

這可能是一個試圖解決人們添加東西到Object.prototype(這是一個非常非常糟糕的主意)。例如:

Object.prototype.foo = "bar"; // <== VERY BAD IDEA 
alert({}.foo); // alerts "bar" 

function Thingy(a, b) { 
    this.a = a; 
    this.b = b; 
} 
Thingy.prototype.x = 42; 

var t = new Thingy(1, 2); 

如果我要複製t,包括其繼承xThingy包括從Object繼承foo財產屬性,我可以使用if (name in {})跳過那些。

你要知道,這不是做一個非常聰明的方式,因爲如果我這樣做會失敗:

var t = new Thingy(1, 2); 
t.foo = "charlie"; 

現在t自己foo,這大概我本來想複製。

更徹底的檢查將是:

dest = {}; 
blank = {}; // No need to recreate it on every iteration 
for (name in src) { 
    if (src.hasOwnProperty(name) || !(name in blank)) { 
     dest[name] = src[name]; 
    } 
} 

這隻會過濾掉了繼承,或者至少會被繼承,從Object的。但即使有缺陷;如果它繼承該屬性的值,而不是從Object價值來決定(例如,一些在中間  — Thingy也許  —已覆蓋Object的默認值)?

因此,您可能需要重構您繼承的代碼,可能是使用hasOwnProperty並確保應用程序中的任何位置不會將事物放在Object.prototype上。

1

如果第二個操作數中包含第一個操作數的標識符,則in operator返回true,否則返回false。因此name in {}檢查是否有名稱爲name的屬性。

這可能看起來很奇怪,因爲{}似乎沒有任何屬性。但是一個普通對象繼承了Object.prototype的一些屬性。所以"toString" in {}返回true,因爲有Object.prototype.toString。也可以使用從Object.prototype.hasOwnProperty繼承的hasOwnProperty方法來代替。

相關問題