在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美

當前位置:雨林木風下載站 > 網頁設計教程 > 詳細頁面

ES6中defineProperty與proxy的詳細介紹(代碼示例)

ES6中defineProperty與proxy的詳細介紹(代碼示例)

更新時間:2025-12-09 文章作者:未知 信息來源:網絡 閱讀次數:

網頁的本質就是超級文本標記語言,通過結合使用其他的Web技術(如:腳本語言、公共網關接口、組件等),可以創(chuàng)造出功能強大的網頁。因而,超級文本標記語言是萬維網(Web)編程的基礎,也就是說萬維網是建立...
網頁的本質就是超級文本標記語言,通過結合使用其他的Web技術(如:腳本語言、公共網關接口、組件等),可以創(chuàng)造出功能強大的網頁。因而,超級文本標記語言是萬維網(Web)編程的基礎,也就是說萬維網是建立在超文本基礎之上的。超級文本標記語言之所以稱為超文本標記語言,是因為文本中包含了所謂“超級鏈接”點。
本篇文章給大家?guī)淼膬热菔顷P于ES6中defineProperty與proxy的詳細介紹(代碼示例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

我們或多或少都聽過“數據綁定”這個詞,“數據綁定”的關鍵在于監(jiān)聽數據的變化,可是對于這樣一個對象:var obj = {value: 1},我們該怎么知道 obj 發(fā)生了改變呢?

definePropety

ES5 提供了 Object.defineProperty 方法,該方法可以在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,并返回這個對象。

語法

Object.defineProperty(obj, prop, descriptor)

參數

obj: 要在其上定義屬性的對象。
prop:  要定義或修改的屬性的名稱。
descriptor: 將被定義或修改的屬性的描述符。

舉個例子:

var obj = {};
Object.defineProperty(obj, "num", {
    value : 1,
    writable : true,
    enumerable : true,
    configurable : true
});
//  對象 obj 擁有屬性 num,值為 1

雖然我們可以直接添加屬性和值,但是使用這種方式,我們能進行更多的配置。

函數的第三個參數 descriptor 所表示的屬性描述符有兩種形式:數據描述符和存取描述符

兩者均具有以下兩種鍵值

configurable

當且僅當該屬性的 configurable 為 true 時,該屬性描述符才能夠被改變,也能夠被刪除。默認為 false。

enumerable

當且僅當該屬性的 enumerable 為 true 時,該屬性才能夠出現在對象的枚舉屬性中。默認為 false。

數據描述符同時具有以下可選鍵值

value

該屬性對應的值。可以是任何有效的 JavaScript 值(數值,對象,函數等)。默認為 undefined。

writable

當且僅當該屬性的 writable 為 true 時,該屬性才能被賦值運算符改變。默認為 false。

存取描述符同時具有以下可選鍵值

get

一個給屬性提供 getter 的方法,如果沒有 getter 則為 undefined。該方法返回值被用作屬性值。默認為 undefined。

set

一個給屬性提供 setter 的方法,如果沒有 setter 則為 undefined。該方法將接受唯一參數,并將該參數的新值分配給該屬性。默認為 undefined。

值得注意的是:

屬性描述符必須是數據描述符或者存取描述符兩種形式之一,不能同時是兩者。這就意味著你可以:

Object.defineProperty({}, "num", {
    value: 1,
    writable: true,
    enumerable: true,
    configurable: true
});

也可以:

var value = 1;
Object.defineProperty({}, "num", {
    get : function(){
      return value;
    },
    set : function(newValue){
      value = newValue;
    },
    enumerable : true,
    configurable : true
});

但是不可以:

// 報錯
Object.defineProperty({}, "num", {
    value: 1,
    get: function() {
        return 1;
    }
});

此外,所有的屬性描述符都是非必須的,但是 descriptor 這個字段是必須的,如果不進行任何配置,你可以這樣:

var obj = Object.defineProperty({}, "num", {});
console.log(obj.num); // undefined

Setters 和 Getters

之所以講到 defineProperty,是因為我們要使用存取描述符中的 get 和 set,這兩個方法又被稱為 getter 和 setter。由 getter 和 setter 定義的屬性稱做”存取器屬性“。

當程序查詢存取器屬性的值時,JavaScript 調用 getter方法。這個方法的返回值就是屬性存取表達式的值。當程序設置一個存取器屬性的值時,JavaScript 調用 setter 方法,將賦值表達式右側的值當做參數傳入 setter。從某種意義上講,這個方法負責“設置”屬性值。可以忽略 setter 方法的返回值。

舉個例子:

var obj = {}, value = null;
Object.defineProperty(obj, "num", {
    get: function(){
        console.log('執(zhí)行了 get 操作')
        return value;
    },
    set: function(newValue) {
        console.log('執(zhí)行了 set 操作')
        value = newValue;
    }
})

obj.value = 1 // 執(zhí)行了 set 操作

console.log(obj.value); // 執(zhí)行了 get 操作 // 1

這不就是我們要的監(jiān)控數據改變的方法嗎?我們再來封裝一下:

function Archiver() {
    var value = null;
    // archive n. 檔案
    var archive = [];

    Object.defineProperty(this, 'num', {
        get: function() {
            console.log('執(zhí)行了 get 操作')
            return value;
        },
        set: function(value) {
            console.log('執(zhí)行了 set 操作')
            value = value;
            archive.push({ val: value });
        }
    });

    this.getArchive = function() { return archive; };
}

var arc = new Archiver();
arc.num; // 執(zhí)行了 get 操作
arc.num = 11; // 執(zhí)行了 set 操作
arc.num = 13; // 執(zhí)行了 set 操作
console.log(arc.getArchive()); // [{ val: 11 }, { val: 13 }]

watch API

既然可以監(jiān)控數據的改變,那我可以這樣設想,即當數據改變的時候,自動進行渲染工作。舉個例子:

HTML 中有個 span 標簽和 button 標簽

<span id="container">1</span>
<button id="button">點擊加 1</button>

當點擊按鈕的時候,span 標簽里的值加 1。

傳統的做法是:

document.getElementById('button').addEventListener("click", function(){
    var container = document.getElementById("container");
    container.innerHTML = Number(container.innerHTML) + 1;
});

如果使用了 defineProperty:

var obj = {
    value: 1
}

// 儲存 obj.value 的值
var value = 1;

Object.defineProperty(obj, "value", {
    get: function() {
        return value;
    },
    set: function(newValue) {
        value = newValue;
        document.getElementById('container').innerHTML = newValue;
    }
});

document.getElementById('button').addEventListener("click", function() {
    obj.value += 1;
});

代碼看似增多了,但是當我們需要改變 span 標簽里的值的時候,直接修改 obj.value 的值就可以了。

然而,現在的寫法,我們還需要單獨聲明一個變量存儲 obj.value 的值,因為如果你在 set 中直接 obj.value = newValue 就會陷入無限的循環(huán)中。此外,我們可能需要監(jiān)控很多屬性值的改變,要是一個一個寫,也很累吶,所以我們簡單寫個 watch 函數。使用效果如下:

var obj = {
    value: 1
}

watch(obj, "num", function(newvalue){
    document.getElementById('container').innerHTML = newvalue;
})

document.getElementById('button').addEventListener("click", function(){
    obj.value += 1
});

我們來寫下這個 watch 函數:

(function(){
    var root = this;
    function watch(obj, name, func){
        var value = obj[name];

        Object.defineProperty(obj, name, {
            get: function() {
                return value;
            },
            set: function(newValue) {
                value = newValue;
                func(value)
            }
        });

        if (value) obj[name] = value
    }

    this.watch = watch;
})()

現在我們已經可以監(jiān)控對象屬性值的改變,并且可以根據屬性值的改變,添加回調函數,棒棒噠~

proxy

使用 defineProperty 只能重定義屬性的讀取(get)和設置(set)行為,到了 ES6,提供了 Proxy,可以重定義更多的行為,比如 in、delete、函數調用等更多行為。

Proxy 這個詞的原意是代理,用在這里表示由它來“代理”某些操作,ES6 原生提供 Proxy 構造函數,用來生成 Proxy 實例。我們來看看它的語法:

var proxy = new Proxy(target, handler);

proxy 對象的所有用法,都是上面這種形式,不同的只是handler參數的寫法。其中,new Proxy()表示生成一個Proxy實例,target參數表示所要攔截的目標對象,handler參數也是一個對象,用來定制攔截行為。

var proxy = new Proxy({}, {
    get: function(obj, prop) {
        console.log('設置 get 操作')
        return obj[prop];
    },
    set: function(obj, prop, value) {
        console.log('設置 set 操作')
        obj[prop] = value;
    }
});

proxy.time = 35; // 設置 set 操作

console.log(proxy.time); // 設置 get 操作 // 35

除了 get 和 set 之外,proxy 可以攔截多達 13 種操作,比如 has(target, propKey),可以攔截 propKey in proxy 的操作,返回一個布爾值。

// 使用 has 方法隱藏某些屬性,不被 in 運算符發(fā)現
var handler = {
  has (target, key) {
    if (key[0] === '_') {
      return false;
    }
    return key in target;
  }
};
var target = { _prop: 'foo', prop: 'foo' };
var proxy = new Proxy(target, handler);
console.log('_prop' in proxy); // false

又比如說 apply 方法攔截函數的調用、call 和 apply 操作。

apply 方法可以接受三個參數,分別是目標對象、目標對象的上下文對象(this)和目標對象的參數數組,不過這里我們簡單演示一下:

var target = function () { return 'I am the target'; };
var handler = {
  apply: function () {
    return 'I am the proxy';
  }
};

var p = new Proxy(target, handler);

p();
// "I am the proxy"

又比如說 ownKeys 方法可以攔截對象自身屬性的讀取操作。具體來說,攔截以下操作:

  • Object.getOwnPropertyNames()

  • Object.getOwnPropertySymbols()

  • Object.keys()

下面的例子是攔截第一個字符為下劃線的屬性名,不讓它被 for of 遍歷到。

let target = {
  _bar: 'foo',
  _prop: 'bar',
  prop: 'baz'
};

let handler = {
  ownKeys (target) {
    return Reflect.ownKeys(target).filter(key => key[0] !== '_');
  }
};

let proxy = new Proxy(target, handler);
for (let key of Object.keys(proxy)) {
  console.log(target[key]);
}
// "baz"

更多的攔截行為可以查看阮一峰老師的 《ECMAScript 6 入門》

值得注意的是,proxy 的最大問題在于瀏覽器支持度不夠,而且很多效果無法使用 poilyfill 來彌補。

watch API 優(yōu)化

我們使用 proxy 再來寫一下 watch 函數。使用效果如下:

(function() {
    var root = this;

    function watch(target, func) {

        var proxy = new Proxy(target, {
            get: function(target, prop) {
                return target[prop];
            },
            set: function(target, prop, value) {
                target[prop] = value;
                func(prop, value);
            }
        });

        if(target[name]) proxy[name] = value;
        return proxy;
    }

    this.watch = watch;
})()

var obj = {
    value: 1
}

var newObj = watch(obj, function(key, newvalue) {
    if (key == 'value') document.getElementById('container').innerHTML = newvalue;
})

document.getElementById('button').addEventListener("click", function() {
    newObj.value += 1
});

我們也可以發(fā)現,使用 defineProperty 和 proxy 的區(qū)別,當使用 defineProperty,我們修改原來的 obj 對象就可以觸發(fā)攔截,而使用 proxy,就必須修改代理對象,即 Proxy 的實例才可以觸發(fā)攔截。

以上就是ES6中defineProperty與proxy的詳細介紹(代碼示例)的詳細內容,更多請關注php中文網其它相關文章!


網站建設是一個廣義的術語,涵蓋了許多不同的技能和學科中所使用的生產和維護的網站。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美
  • <li id="86scu"><menu id="86scu"></menu></li>
    <li id="86scu"></li>
    <button id="86scu"></button>
  • <s id="86scu"></s><button id="86scu"><menu id="86scu"></menu></button>
  • 肉大捧一出免费观看网站在线播放| 鲁一鲁一鲁一鲁一澡| 影音先锋男人的网站| 欧美极品少妇无套实战| 男人的天堂狠狠干| 日本一二区免费| 久久男人资源站| 午夜欧美福利视频| 欧美三级午夜理伦三级老人| 国产 福利 在线| 日本丰满少妇黄大片在线观看| 69sex久久精品国产麻豆| 国产91在线免费| 9191国产视频| 日本一二三四区视频| 午夜精品久久久久久久无码| 久久久久亚洲av无码专区喷水| 国产成人精品无码播放| 免费超爽大片黄| 一区二区久久精品| 少妇一级淫免费放| 免费毛片小视频| 无码专区aaaaaa免费视频| 色乱码一区二区三区熟女| av在线网址导航| 亚洲五月天综合| 鲁一鲁一鲁一鲁一澡| 国产青草视频在线观看| 色姑娘综合天天| 99九九精品视频| 天天综合成人网| 污污网站免费看| 亚洲免费成人在线视频| 亚洲成人福利在线| 国产精品拍拍拍| 不卡中文字幕在线观看| 中文字幕第一页在线视频| 国产精品999.| 亚洲精品天堂成人片av在线播放| 一本—道久久a久久精品蜜桃| 第四色婷婷基地| 日日干日日操日日射| 一区二区久久精品| 黄瓜视频免费观看在线观看www| 天天干天天曰天天操| 中文精品无码中文字幕无码专区| 97视频在线免费| 黄色av免费在线播放| 亚洲精品手机在线观看| 在线观看三级网站| 给我免费播放片在线观看| 国内外免费激情视频| 黄网站色视频免费观看| 国内外成人免费激情视频| 91国产精品视频在线观看| 在线观看污视频| 亚洲 欧美 另类人妖| 黄色网络在线观看| av观看免费在线| 福利在线小视频| 992kp快乐看片永久免费网址| 色中文字幕在线观看| 欧美极品欧美精品欧美| 伊人成人免费视频| 五月婷婷六月合| 国产无套粉嫩白浆内谢的出处| 久久手机在线视频| 国产精品无码电影在线观看| av无码精品一区二区三区| 只有这里有精品| 亚洲一区二区在线视频观看| 久久网站免费视频| 女人另类性混交zo| 黑森林福利视频导航| 成人免费观看cn| 久久国产成人精品国产成人亚洲| 国产免费内射又粗又爽密桃视频| 视频一区二区视频| 成年人视频大全| 国产成人一二三区| 欧美一区二区激情| 亚洲熟妇无码另类久久久| 日韩av综合在线观看| 亚洲精品乱码久久久久久自慰| 日韩av一二三四| 15—17女人毛片| 国产乱女淫av麻豆国产| 福利在线小视频| 国产美女无遮挡网站| 天堂av在线网站| 深爱五月综合网| 国产成人一二三区| 成人免费观看cn| 成人性生生活性生交12| 一区二区成人网| 91九色国产ts另类人妖| 视色,视色影院,视色影库,视色网| 久久免费看毛片| 日本一本中文字幕| 天天操天天爽天天射| 日韩视频一二三| av免费播放网址| 青青草原播放器| 蜜臀av午夜一区二区三区 | 午夜激情视频网| 国产网站免费在线观看| 色婷婷一区二区三区av免费看| 免费极品av一视觉盛宴| 国产乱子伦农村叉叉叉| 911av视频| 婷婷丁香激情网| 国产特级淫片高清视频| 久久精品国产精品亚洲精品色| 日日摸日日碰夜夜爽无码| 五月天视频在线观看| 久久久一本二本三本| 午夜视频在线观| 亚洲77777| 精品久久久久久久无码| 黄色一级片播放| 3d动漫一区二区三区| 日韩美女爱爱视频| 国产小视频免费| 欧美黄网站在线观看| 国产片侵犯亲女视频播放| 尤物网站在线看| 在线观看的毛片| 成人在线免费观看av| 国产综合av在线| 波多野结衣家庭教师在线| 国产 日韩 欧美在线| av一区二区三区免费观看| 国产成人在线小视频| 欧美日韩黄色一级片| 国产精品自拍片| 日韩人妻精品无码一区二区三区| 日韩免费高清在线| 中日韩av在线播放| 不卡的在线视频| 中文字幕亚洲影院| 日韩不卡视频一区二区| 久久手机在线视频| 日韩精品一区二区三区久久| 99视频精品免费| 只有这里有精品| 国产免费黄色小视频| 午夜国产一区二区三区| 久久国产激情视频| 91网站在线观看免费| 美女日批免费视频| 爱情岛论坛成人| 欧美一级视频在线播放| 88av.com| 91xxx视频| 成年人免费在线播放| 超碰成人在线免费观看| 国产精品入口芒果| 久久久久久久高清| 丰满的少妇愉情hd高清果冻传媒| 91香蕉视频污版| 欧美性潮喷xxxxx免费视频看| 一级特黄性色生活片| 国产成人艳妇aa视频在线 | 大地资源第二页在线观看高清版| 国产精品国三级国产av| 粉色视频免费看| www一区二区www免费| 精品嫩模一区二区三区| 污网站在线免费| 亚洲怡红院在线| 色噜噜狠狠一区二区| 日韩福利视频在线| 国产第一页视频| 欧美精品无码一区二区三区| 99免费视频观看| 男女污污的视频| www.com黄色片| 妞干网在线免费视频| 久久久久久免费看| 搡的我好爽在线观看免费视频| 欧美性猛交久久久乱大交小说| 亚洲国产精品女人| 亚洲国产精品影视| 性生活免费在线观看| 成年人免费在线播放| 国产午夜伦鲁鲁| 亚洲美免无码中文字幕在线| 黄色一级片免费播放| 91福利免费观看| 亚洲精品自拍网| 亚洲天堂2018av| 亚洲第一精品区| 欧美中文字幕在线观看视频| 成年人黄色在线观看| 天天操天天干天天玩| 青青草综合视频| 黄色网页免费在线观看| 国产一区亚洲二区三区| 男人的天堂日韩| 亚洲欧美偷拍另类|