欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

你的 mixin 真的兼容 ECMAScript 5 嗎?

 更新時(shí)間:2013年04月11日 14:34:26   作者:  
本篇文章主要講述了,在JavaScript 中把一個(gè)對(duì)象的屬性或者方法 mixin 到另一個(gè)

我最近在與客戶合作的項(xiàng)目中,需要充分利用的 ECMAScript 5,在此我遇到一個(gè)非常有趣的問(wèn)題。 該問(wèn)題源于一個(gè)非常常見(jiàn)的模式: mixin , 也就是在 JavaScript 中把一個(gè)對(duì)象的屬性或者方法 mixin 到另一個(gè)。

大多數(shù) mixin 的功能看起來(lái)像這樣:

復(fù)制代碼 代碼如下:

function mixin(receiver, supplier) {
    for (var property in supplier) {
        if (supplier.hasOwnProperty(property)) {
            receiver[property] = supplier[property];
        }
    }
}

在此 mixin() 函數(shù)中,一個(gè) for 循環(huán)遍歷 supplier 對(duì)象的屬性并賦值給 receiver 對(duì)象。 幾乎所有的 JavaScript 庫(kù)有某種形式的類似功能,讓您可以編寫(xiě)這樣的代碼:

復(fù)制代碼 代碼如下:

mixin(object, {
    name: "Nicholas",

    sayName: function() {
        console.log(this.name);
    }
});

object.sayName();       // outputs "Nicholas"

在此示例中,object 對(duì)象接收了屬性 name 和方法 sayName()。 這在 ECMAScript 3 中運(yùn)行良好,但在 ECMAScript 5 上卻沒(méi)那么樂(lè)觀。

這是我遇到的問(wèn)題:

復(fù)制代碼 代碼如下:

(function() {

    // to be filled in later
    var name;

    mixin(object, {
        get name() {
            return name;
        }
    });

    // let's just say this is later
    name = "Nicholas";

}());

console.log(object.name);       // undefined

這個(gè)例子看起來(lái)有點(diǎn)做作,但它準(zhǔn)確的描述這個(gè)問(wèn)題。 進(jìn)行 mixin 的屬性使用了 ECMAScript 5 的新特性:一個(gè) getter 屬性存取器。 getter 引用一個(gè)未初始化的局部變量 name,因此這個(gè)屬性未定義 undefined。

后來(lái),name 被分配了一個(gè)值,以便使存取器 getter 可以返回一個(gè)有效的值。 不幸的是,object.name(被 mixin 的屬性)始終返回 undefined。

這是怎么回事呢?

我們仔細(xì)分析 mixin() 函數(shù)。 事實(shí)上,在循環(huán)語(yǔ)句中,并沒(méi)有把屬性從一個(gè)對(duì)象重新賦值給到另一個(gè)對(duì)象。 它實(shí)際上是創(chuàng)建一個(gè)同名的屬性,并把 supplier 對(duì)象的存取器方法 getter 的返回值賦值給了它。 (譯注:目標(biāo)對(duì)象得到的不是 getter 這個(gè)方法,而是得到了 getter 方法的返回值。@justjavac)

在這個(gè)例子中,mixin() 的過(guò)程其實(shí)是這樣的:

復(fù)制代碼 代碼如下:

receiver.name = supplier.name;

屬性 receiver.name 被創(chuàng)建,并且被賦值為 supplier.name 的值。 當(dāng)然,supplier.name 有一個(gè) getter 方法用來(lái)返回本地變量 name 的值。 此時(shí),name 的值為 undefined,所以 receiver.name 存儲(chǔ)的是 值。 并沒(méi)有為 receiver.name 創(chuàng)建一個(gè) getter 方法,因此它的值永遠(yuǎn)不會(huì)改變。

要解決這個(gè)問(wèn)題,你需要使用屬性描述符(譯注:descriptor)將屬性從一個(gè)對(duì)象 mixin 到另一個(gè)對(duì)象。 一個(gè)純粹的 ECMAScript 5 版本的 mixin() 應(yīng)該這樣寫(xiě):

復(fù)制代碼 代碼如下:

function mixin(receiver, supplier) {

    Object.keys(supplier).forEach(function(value, property) {
        Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));
    });
}

在這個(gè)新版本函數(shù)中,Object.keys() 用來(lái)獲取一個(gè)數(shù)組,包含了 supplier 對(duì)象的所有枚舉屬性。 然后,foreach() 方法用來(lái)遍歷這些屬性。 調(diào)用 Object.getOwnPropertyDescriptor() 方法獲取 supplier 對(duì)象的每個(gè)屬性描述符(descriptor)。

由于描述符(descriptor)包含了所有的屬性信息,包括 getter 和 setter 方法, 該描述符(descriptor)可以直接傳遞給 Object.defineProperty() ,用來(lái)在 receiver 對(duì)象上創(chuàng)建相同的屬性。 使用這個(gè)新版本的 mixin() ,可以解決前面遇到的問(wèn)題,從而得到你所期望的結(jié)果。 getter 方法被正確地從 supplier 傳遞到了 receiver。

當(dāng)然,如果你仍然需要支持舊的瀏覽器,那么你就需要一個(gè)函數(shù),回落的 ECMAScript 3:

復(fù)制代碼 代碼如下:

function mixin(receiver, supplier) {
    if (Object.keys) {
        Object.keys(supplier).forEach(function(value, property) {
            Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));
        });
    } else {
        for (var property in supplier) {
            if (supplier.hasOwnProperty(property)) {
                receiver[property] = supplier[property];
            }
        }
    }
}

如果您需要使用一個(gè) mixin() 函數(shù),一定要仔細(xì)檢查它在 ECMAScript 5 可以正常工作,特別是 getter 和 setter 方法。 否則,你會(huì)發(fā)現(xiàn)自己陷入像我一樣的錯(cuò)誤。

相關(guān)文章

  • 淺談checkbox的一些操作(實(shí)戰(zhàn)經(jīng)驗(yàn))

    淺談checkbox的一些操作(實(shí)戰(zhàn)經(jīng)驗(yàn))

    checkbox看起來(lái)很簡(jiǎn)單,有時(shí)很頭疼,有什么難的,下面就為大家介紹下checkbox的一些操作,不了解的朋友不要錯(cuò)過(guò)
    2013-11-11
  • javascript cookie基礎(chǔ)應(yīng)用之記錄用戶名的方法

    javascript cookie基礎(chǔ)應(yīng)用之記錄用戶名的方法

    這篇文章主要介紹了javascript cookie基礎(chǔ)應(yīng)用之記錄用戶名的方法,涉及javascript基于cookie針對(duì)數(shù)據(jù)存儲(chǔ)的簡(jiǎn)單應(yīng)用,需要的朋友可以參考下
    2016-09-09
  • window.parent與window.openner區(qū)別介紹

    window.parent與window.openner區(qū)別介紹

    今天總結(jié)一下js中幾個(gè)對(duì)象的區(qū)別和用法,對(duì)這幾個(gè)概念混淆的朋友可以看看
    2012-04-04
  • 了解javascript中l(wèi)et和var及const關(guān)鍵字的區(qū)別

    了解javascript中l(wèi)et和var及const關(guān)鍵字的區(qū)別

    這篇文章主要介紹了javascript中l(wèi)et和var以及const關(guān)鍵字的區(qū)別,下面我們來(lái)一起學(xué)習(xí)一下吧
    2019-05-05
  • JS和jquery獲取各種屏幕的寬度和高度的代碼

    JS和jquery獲取各種屏幕的寬度和高度的代碼

    這篇文章介紹了JS和jquery獲取各種屏幕的寬度和高度的代碼,有需要的朋友可以參考一下
    2013-08-08
  • 最新評(píng)論