JavaScript伺服器編程(對象屬性枚舉中應當避免原型汙染問題)

來源:互聯網
上載者:User

標籤:javascript 伺服器編程 對象屬性枚舉 原型汙染

        前面文章中討論了JS開發中對象屬性枚舉的ES3和ES5方案並給出了一組常用工具函數,其實,企業開發中真正應用時還存在不少問題。本文想基於前文進一步探討一下有關原型汙染的問題。由於JS的先天不足,有關原型汙染背後隱藏著一個大的“故事”,以後我們的文章中還要涉及其中一些情節。

 

問題

前面在討論使用in運算子檢測對象中是否存在屬性的方案,但是通過所舉的樣本也發現一個問題,例如:

console.log(‘"ID" in contacts: ‘,"ID" in contacts);

其輸出結果也是true。這說明in運算子在屬性檢測時不僅搜尋當前對象的自有屬性,還會沿著對象的原型鏈搜尋。

根據前面對於屬性繼承的分析可得知,JS中的對象總是以繼承的方式工作,即使是一個空的對象字面量也會繼承Object.prototype的大量屬性。因此,對於下面的測試結果正在我們的意料之中:

var pol={};

console.log("Hi" in pol);  //false

console.log("toString" in pol);  //true

console.log("valueOf" in pol);  //true

console.log("constructor" in pol);  //true

console.log("__defineGetter__" in pol);  //true

console.log("__defineSetter__" in pol);  //true

console.log("__lookupGetter__" in pol);  //true

console.log("__lookupSetter__" in pol);  //true

console.log("hasOwnProperty" in pol);  //true

console.log("isPrototypeOf" in pol);  //true

console.log("propertyIsEnumerable" in pol);  //true

console.log("toLocaleString" in pol);  //true

而在ES5中使用Object.prototype中的hasOwnProperty方法正好可以避免上面的問題,因為它只檢索對象的自有屬性,包括不可枚舉的屬性(ES3中沒有定義這樣的概念)。

更進一步

如果對象本身有一個自有屬性hasOwnProperty,情況又該如何呢?參考如下代碼:

var o={};

o.hasOwnProperty="*********";

console.log(o.hasOwnProperty("Alice");

運行測試時,出現如所示的執行階段錯誤:

650) this.width=650;" title="無標題.jpg" src="http://s3.51cto.com/wyfs02/M00/6D/28/wKiom1VdeFzzyFEeAAFdskcrBaM427.jpg" alt="wKiom1VdeFzzyFEeAAFdskcrBaM427.jpg" />

對於這種情況,專家的建議是“最安全的方法是不做任何假設”。於是,我們可以提前在任何安全的位置提取出hasOwnProperty方法,同時利用立即執行的匿名函數的詞法範圍特點,實現如下解決方案:

(function testOwnProperty(){

    //var hasOwn=Object.prototype.hasOwnProperty;也可以使用如下更簡潔方式

    var hasOwn={}.hasOwnProperty;

 

    var dict={};

    dict.Alice=12;

    console.log("------------");

    console.log(hasOwn.call(dict,"hasOwnProperty"));

    console.log(hasOwn.call(dict,"Alice"));

    dict.hasOwnProperty=100;

    console.log("-------------");

    console.log(hasOwn.call(dict,"hasOwnProperty"));

    console.log(hasOwn.call(dict,"Alice"));

    console.log("---------------");

})();

於是,不管對象的hasOwnProperty方法是否被覆蓋,上述方案都能夠正常工作。值得注意的是,許多知名JS庫就是利用了上述技術。

本文出自 “青峰” 部落格,請務必保留此出處http://zhuxianzhong.blog.51cto.com/157061/1653484

JavaScript伺服器編程(對象屬性枚舉中應當避免原型汙染問題)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.