摘要:今天看你不知道的第五章原型的時候,注意到一個關于屬性設置的有意思的地方。但沒想到,還有其他不能添加新屬性的情況。原型鏈上有同名的存取器屬性,且至少設置了。規(guī)則這里以設置為例。那么當我們遇到關于這些知識的的時候,就會很快將問題解決了。
今天看《你不知道的JavaScript》第五章——原型的時候,注意到一個關于JavaScript屬性設置的有意思的地方。(P145)
之前,我以為除了對象被設置為不可擴展的情況,其他情況下給對象添加新屬性都會成功。但沒想到,還有其他不能添加新屬性的情況。我所說的這種情況,就是原型鏈上有與你將要添加的屬性同名的屬性的時候。
分類原型鏈上有與你將要添加的屬性同名的屬性的情況,還要分成三種情況:
原型鏈上有同名的數(shù)據(jù)屬性并且沒有被標記為只讀,即writable: true。
原型鏈上有同名的數(shù)據(jù)屬性,但它被標記為只讀,即writable: false。
原型鏈上有同名的存取器屬性,且至少設置了setter。
規(guī)則這里以設置myObject.foo = "my"為例。
同名數(shù)據(jù)屬性、可讀如果在[[Prototype]]鏈上層存在名為foo的普通數(shù)據(jù)訪問屬性并且沒有被標記為只讀(wirtable: false),那么就會在myObject中添加一個名為foo的新屬性,它就是屏蔽屬性。
這種情況是最常見的,下面貼一個簡單的例子。
var proObject = { foo: "pro" } var myObject = Object.create(proObject) myObject.foo = "my" myObject.foo // "my" myObject.hasOwnProperty("foo") // true同名數(shù)據(jù)屬性、只讀
如果在[[Prototype]]鏈上層存在foo,但是它被標記為只讀(writable: false),那么無法修改已有屬性或者在myObject上創(chuàng)建屏蔽屬性。如果運行在嚴格模式下,代碼會拋出一個錯誤。否則,這條賦值語句會被忽略。
var proObject = {} Object.defineProperty(proObject, "foo", { value: "pro", wirtable: false }) var myObject = Object.create(proObject) myObject.foo = "my" myObject.foo // "pro" myObject.hasOwnProperty("foo") // false "use strict" myObject.foo = "my" // Uncaught TypeError: Cannot assign to read only property "foo" of object "#同名的存取器屬性
如果在[[Prototype]]鏈上層存在foo并且它是一個setter,那就一定會調(diào)用這個setter。foo不會被添加到(或者說屏蔽于)myObject,也不會重新定義foo這個setter。
var proObject = {} Object.defineProperty(proObject, "foo", { set: function(val) { this.s = val }, get: function() { return this.s } }) myObject.foo = "my" myObject.hasOwnProperty("foo") // false // 可以看到存取器屬性沒有被重新定義 Object.getOwnPropertyDescriptor(proObject, "foo")解決方案
如果你希望在上述的第二和第三中情況下為myObject添加新屬性的話,你需要使用Object.defineProperty或者Object.getOwnPropertyDescriptors來添加新屬性。
結語終于在周日完成了這周的博客文章了(雖然很無恥地“水了一篇”,但好歹也算一篇文章嘛。)
正經(jīng)一點?。?!JavaScript中還有很多讓我們出乎意料的地方,雖然平時很少遇到這些方面知識的應用,但一旦踩了這些坑,還是會耗掉我們挺多時間和精力的。所以,我們平時應該多留意這些知識,并積累下來。那么當我們遇到關于這些知識的bug的時候,就會很快將問題解決了。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88015.html
摘要:最近剛剛看完了你不知道的上卷,對有了更進一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對象類類理論類的機制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進一步的了解。 《你不知道的 JavaScript》上卷由兩部...
摘要:而在構造函數(shù)中,返回了的實例對象。在中直接返回過的實例,這里的是的真正構造函數(shù)最后對外暴露入口時,將字符與對等起來。因此當我們直接使用創(chuàng)建一個對象時,實際上是創(chuàng)建了一個的實例,這里的正真構造函數(shù)是原型中的方法。 showImg(https://segmentfault.com/img/remote/1460000008749398); 早幾年學習前端,大家都非常熱衷于研究jQuery源...
閱讀 1582·2021-11-16 11:44
閱讀 7423·2021-09-22 15:00
閱讀 4462·2021-09-02 10:20
閱讀 1944·2021-08-27 16:20
閱讀 2385·2019-08-26 14:00
閱讀 2905·2019-08-26 11:44
閱讀 1627·2019-08-23 18:33
閱讀 1853·2019-08-22 17:28