2013-07-18 19 views
2

嗯,我試圖在Chrome中使用Object.watch的polyfill時遇到了問題。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch https://gist.github.com/eligrey/384583Object.defineProperty在鉻devtool下看不見的道具

的填充工具是很短的一個,你可以看它是如何刪除原來的財產和馬上定義一個新的屬性相同的值,但覆蓋getter和setter。

的問題是,如果你使用這個填充工具和觀看o.p:

var o = { p: 1 }; 
o.watch("p", function (id, oldval, newval) { 
    console.log("o." + id + " changed from " + oldval + " to " + newval); 
    return newval; 
}); 

之後,你檢查對象o下鍍鉻devtool。砰!對象o現在是空的!其實它仍然有po.p,你會發現o.p = 1

我的問題是,爲什麼該屬性在Chrome開發人員工具對象屬性列表下不可見?

注意:如果您不知道/感興趣的Object.watch,您可能仍然可以幫助我解決這個問題,只要您明白Object.defineProperty


編輯:事實證明,它沒有像我認爲它創建一個新的屬性,只是重寫它的getter和setter。 引用來自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty 「存在於對象中的屬性描述符有兩種主要形式:數據描述符和訪問符描述符。數據描述符是一個具有值的屬性,該值可以是也可以不是可寫的。一個吸氣定位器對功能「。

因此,看起來polyfill將目標屬性從「數據屬性」更改爲「訪問器屬性」。我認爲這是唯一的方法來填充這個?

+0

它不是不可見的,它由'watch'填充變爲'getter'和'setter'。這是'watch'知​​道它何時被修改的方式。 – Xotic750

+0

Òk,如果你讀了代碼,你會看到它做了一個副本,刪除舊的屬性並重新添加該屬性作爲一個getter和setter舊值。 - >更改 – Xotic750

+0

我可以看到它。 [jsfiddle](http://jsfiddle.net/Xotic750/FUJ5h/) – Xotic750

回答

2
我的問題是,爲什麼Chrome開發人員工具對象屬性列表中的屬性不可見?

答案是:它是可見的,但現在它是一個getter和setter。

Object {} 
get p: function() { 
set p: function (val) { 
__proto__: Object 

jsfiddle

如果不過,你會問,爲什麼你不能看到它的價值:那是因爲值現在是私人的,只能通過吸氣讀取。

console.log(o.p); 

更新:閱讀Mutator method

賦值函數方法

維基百科,自由的百科全書

在計算機科學中,突變 方法是用來控制變化的方法到一個 變量。他們也被廣泛地稱爲'''setter'''方法。通常一個 setter會伴隨一個'''getter'''(也稱爲訪問器),它會返回私有成員變量的值,即 。方法,有時稱爲「setter」,最常用於面向對象編程,與封裝的原理保持一致。根據這個原則, 類的成員變量被隱藏起來以隱藏並保護它們免受其他代碼的影響,並且 只能被公共成員函數(增變器方法) 修改,該函數將所需的新值作爲參數,可以選擇驗證 它,並修改私有成員變量。

考慮這個例子

function MyClass() { 
    var privateVar = 0; 

    this.getPrivate = function() { 
     return privateVar; 
    } 

    this.setPrivate = function (value) { 
     privateVar = value; 
    } 
} 

var newObject = new MyClass(); 

console.log(newObject); 

console.log(newObject.getPrivate()); 

輸出

MyClass {getPrivate: function, setPrivate: function} 
getPrivate: function() { 
setPrivate: function (value) { 
__proto__: MyClass 

0 

jsfiddle

您可以查看對象,看到的公共方法getPrivatesetPrivate(類似於太真實幹將和二傳手由Object.defineProperty創建),但是看不到成員變量privateVariable的值。您只能通過調用getPrivate公共方法查看該值。

+1

Thx但老實說,我不接受這個答案,因爲這真的沒有多少解釋。是的,有一對get/set p來代替'property p'。我可以假設有很多人認爲這個觀察到的事實有點令人困惑。我希望這個問題可以導致一些解釋,所以我/我們可以更多地理解Object.defineProperty,從而更多地理解javascript對象的屬性。 – kakacii

+1

@kakacii它回答了你的問題,_「爲什麼財產是隱形的?」_; _「不是。」_考慮改寫你的問題。 – canon

+0

@ Xotic750我看到你的更新。我感謝你幫助人們的努力,但沒有冒犯,要麼是過分簡化了事情,要麼是你是一位js大師。我只是認爲「對象中存在的屬性描述符有兩種主要的風格:數據描述符和訪問符描述符」,這是違反直覺的,看起來不是一個好的設計。也許這只是我。 – kakacii