目錄javascript
JavaScript共享的本質一直是開發人員心頭的痛,由於任何對象均可以被在同一個環境中運行的代碼修改。前端
ECMAScript5致力於解決這個問題,可讓開發人員定義防篡改對象
(tamper-proof object)。它的原理就是java
經過設置每一個對象的屬性的一下的默認屬性:git
下面咱們就針對以上每個屬性進行 解析一下:github
// Demo one var o = {} Object.defineProperty(o, 'name', { value: 'zhang', configurable: false }) console.log(o) Object.defineProperty(o, 'name', { writable: false }) o.name = 'Li' console.log(o) // {name: 'zhange'} 屬性未被改變
上面的 Demo 中 咱們將 configurable 屬性設置成爲 false, 再對比下面的 Demo 來看 configurable 屬性做用瀏覽器
// Demo two var o = {} Object.defineProperty(o, 'name', { value: 'zhang', configurable: false }) console.log(o) Object.defineProperty(o, 'name', { writable: true }) o.name = 'Li' // Uncaught TypeError: Cannot redefine property: name 報錯
總結: 當 [[Configurable]] 爲 fasle 的時候 [[Writable]] 默認已經被設置 false, 若是去修改 [[Writable]] 的時候
則會報錯。 那麼咱們就能夠理解爲 當 [[Configurable]] 爲 false 的時候, [[Writable]] 是隻能爲 false的。函數
咱們仍是用 Demo 來進行對比解釋:this
var o = {} Object.defineProperty(o, 'age', { enumerable: true, value: 18 }) for(item in o) { console.log(item, o[item]) // age 18 }
把 enumerable 設置成 falseprototype
var o = {} Object.defineProperty(o, 'age', { enumerable: false, value: 19 }) for(item in o) { console.log(item, o[item]) // undefined }
get 和 set 這對雙胞胎咱們已經說過屢次了。此次咱們仔細來看下這個~code
var o = {} var v = 'coder' Object.defineProperty(o, 'job', { get: function() { console.log('get:', v) return v }, set: function(newV) { console.log('set:', newV) v = newV } }) o.job = 'xxx' // set: xxx // 很奇怪的一點就是 當咱們在 瀏覽器控制檯點開 o 對象的時候,再次去點擊 job 屬性,就會觸發 get 方法。
Object.preventExtensions(o)
可使得 不能再給對象添加屬性和方法
var o = {name: 'zhang'} Object.preventExtensions(o) o.age = '12' console.log(o) // {name: 'zhang'} // 已經阻止了給對象添加屬性和方法了。再去添加 也未能添加上
Object.isExtensible(o)
肯定對象是否能夠擴展
var o = {name: 'zhang'} var res1 = Object.isExtensible(o) Object.preventExtensions(o) var res2 = Object.isExtensible(o) console.log(res1, res2) // true false
Object.seal(o)
密封對象不可擴展,並且已有成員的[[Configurable]]特性被設置爲false,意味着不能刪除屬性和方法。不可增長,不能刪除。
var o = {name: 'Li'} Object.isSealed(o) // false Object.seal(o) Object.isSealed(o) // true
Object.isSealed(o)
檢測時候被密封了(🐝 )
Object.freeze(o)
最嚴格的防篡改級別就是凍結對象(frozen object)。凍結的對象不能擴展,又是密封的,並且對象屬性的[[Writable]]特性會被設置爲false。
若是定義了[[Set]]函數,訪問器屬性仍然是可寫的。
var obj = {age: 123} Object.freeze(obj) Object.isFrozen(obj) // true Object.isSealed(obj) // true Object.isExtensible(obj) // false
Object.isFrozen(o)
檢查是否被凍結
基於
觀察者模式
的一種建立鬆散耦合代碼的技術。使用自定義事件有助於解耦相關對象,保持功能的隔絕。
function EventTarget(){ this.handlers = {}; } EventTarget.prototype = { constructor : EventTraget, addHandler : function(type,handler){ if(typeof this.handlers[type] === 'undefined'){ this.handlers[type] = []; } this.handlers[type].push(handler); }, fire : function(event){ if(!event.target){ event.target = this; } if(this.handlers[type] instanceof Array){ var handlers = this.handlers[event.type]; for(var i = 0,len = handlers.length; i < len; i++){ handlers[i](event);//執行回調函數 } } }, removeHandler : function(type,handler){ if(this.handlers[type] instanceof Array){ var handlers = this.handlers[type]; for(var i = 0,len = handlers.length; i < len; i++){ if(handlers[i] === handler){ break; } } handlers.splice(i,1);//刪除 } } }
總結: 以上則爲高階函數中的相關的一些場景的應用,可是這也僅僅是屬於基礎部分,實際的使用場景還須要你們本身靈活處理。
好了,本期這篇 blog 就先寫到這裏。
GitHub 地址:(歡迎 star 、歡迎推薦 : )