《前端之路》之 JavaScript 進階技巧之高階函數(下)

來源:互聯網
上載者:User

目錄

  • 第二章 - 03: 前端 進階技巧之高階函數
    • 一、防篡改對象
      • 1-1:Configurable 和 Writable
      • 1-2:Enumerable
      • 1-3:get 、set
      • 2-1:不可擴充項物件
      • 2-2:密封的對象
      • 2-3:凍結的對象
    • 二、自訂事件
第二章 - 03: 前端 進階技巧之高階函數一、防篡改對象

JavaScript共用的本質一直是開發人員心頭的痛,因為任何對象都可以被在同一個環境中啟動並執行代碼修改。

ECMAScript5致力於解決這個問題,可以讓開發人員定義防篡改對象(tamper-proof object)。它的原理就是

通過設定每個對象的屬性的一下的預設屬性:

  • [[Configurable]] --- 是否可配置
  • [[Writable]] --- 是否可以重新賦值
  • [[Enumerable]] --- 是否可列舉的
  • [[Value]] --- 預設值
  • [[Get]]
  • [[Set]]
1-1:Configurable 和 Writable

下面我們就針對以上每一個屬性進行 解析一下:

// Demo onevar 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 twovar 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的。

1-2:Enumerable

我們還是用 Demo 來進行對比解釋:

var o = {}Object.defineProperty(o, 'age', {    enumerable: true,    value: 18})for(item in o) {    console.log(item, o[item])   // age 18}

把 enumerable 設定成 false

var o = {}Object.defineProperty(o, 'age', {    enumerable: false,    value: 19})for(item in o) {    console.log(item, o[item])   // undefined}
1-3:get 、set

get 和 set 這對雙胞胎我們已經說過多次了。這次我們仔細來看下這個~

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 方法。
2-1:不可擴充項物件

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
2-2:密封的對象

Object.seal(o)
密封對象不可擴充,而且已有成員的[[Configurable]]特性被設定為false,意味著不能刪除屬性和方法。不可增加,不能刪除。

var o = {name: 'Li'}Object.isSealed(o)  // falseObject.seal(o)Object.isSealed(o)  // true

Object.isSealed(o)
檢測時候被密封了( )

2-3:凍結的對象

Object.freeze(o)

最嚴格的防篡改層級就是凍結對象(frozen object)。凍結的對象不能擴充,又是密封的,而且對象屬性的[[Writable]]特性會被設定為false。

如果定義了[[Set]]函數,訪問器屬性仍然是可寫的。

var obj = {age: 123}Object.freeze(obj)Object.isFrozen(obj)            // trueObject.isSealed(obj)            // trueObject.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 、歡迎推薦 : )

前端 進階技巧之高階函數(下)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.