簡體   English   中英

使用Object.defineProperty中具有自執行功能的構造函數中的“ this”構造新對象后的未定義屬性

[英]Undefined Property after new object construction using 'this' in constructor with self-executing function inside Object.defineProperty

我正在嘗試使用一種類似TypeScript的結構來仿真“ value:”屬性的自執行函數中的枚舉。 我檢查了所有在構造函數中使用ECMAScript5 / Crockford Object.defineProperty()的示例(使用'this'),但找不到太多。 據我所知,自執行函數應該用10個屬性填充兩個對象,並且閉包是正確的(“ this”不是window對象)。 這是我的設計模式:

var player = {};
var Foo = function () {
    this.levelIndex;
    Object.defineProperty(this, 'levelIndex', {
        value: (function (levelIndex) {
            levelIndex[levelIndex.ONE =   0] = 'ONE';
            levelIndex[levelIndex.TWO =   1] = 'TWO';
            levelIndex[levelIndex.THREE = 2] = 'THREE';
            levelIndex[levelIndex.FOUR =  3] = 'FOUR';
            levelIndex[levelIndex.FIVE =  4] = 'FIVE';
            // setup the player object with the properties of the levelIndex
            // before it becomes non-enumerable:
            for (var i in levelIndex) {
                Object.defineProperty(player, i, {
                  value: isNaN(levelIndex[i]) ? 'LEVEL_' + levelIndex[i] : levelIndex[i],
                  enumerable: false
                });
                alert(player[i]); //<-- LEVEL_ONE, LEVEL_TWO, LEVEL_THREE, LEVEL_FOUR, LEVEL_FIVE, 0, 1, 2, 3, 4
            }
            alert('window? : ' + this === window); //<-- false
        })(this.levelIndex || (this.levelIndex = {})),
        writable: false,
        enumerable: false,
        configurable: false
    });
};
var foo = new Foo();
alert(player.ONE); //<-- 0
alert(foo.levelIndex); //<-- undefined
alert(foo.levelIndex.ONE); //<-- Uncaught TypeError: Cannot read property 'ONE' of undefined 

為什么在這里未定義foo.levelIndex

編輯:固定與return levelIndex; 添加到匿名函數調用中。

歡迎對我的設計模式提出任何意見或提出改進建議!

你調用一個普通的函數調用的匿名函數,所以價值thisundefined嚴格模式,或全局對象( window ),否則。 絕對不會是對您所定義的對象文字的引用。

您的“ Foo”功能的第一行看起來有點可疑:

    this.levelIndex;

那將不會對任何事物產生影響; 具體而言,也不會造成那里是一個名為“levelIndex”被引用的對象上創建屬性this

編輯 -同樣,當我更多地查看您的操作時,很清楚為什么“ levelIndex”屬性最終undefined :該對象文字具有一個“ value”屬性,該屬性設置為該匿名函數調用的返回值。 但是,匿名函數沒有return語句,因此對Object.defineProperty的調用涉及一個屬性對象,該屬性對象的“值”屬性設置為undefined 如果添加

    return levelIndex;

到該匿名函數的末尾,它( 可能 )有效。 (我認為是。)

基於@Pointy和@Bergi的幫助,以下是更新的工作代碼:

http://jsfiddle.net/5j9W5/

var player = {};
var Foo = function () {
    Object.defineProperty(this, 'levelIndex', {
        value: (function (levelIndex) {
            levelIndex[levelIndex.ONE = 0] = 'ONE';
            levelIndex[levelIndex.TWO = 1] = 'TWO';
            levelIndex[levelIndex.THREE = 2] = 'THREE';
            levelIndex[levelIndex.FOUR = 3] = 'FOUR';
            levelIndex[levelIndex.FIVE = 4] = 'FIVE';
            return levelIndex;
        })(this.levelIndex || (this.levelIndex = {})),
        writable: false,
        enumerable: false,
        configurable: false
    });
    // setup the player object with the properties of the levelIndex:
    for (var i in this.levelIndex) {
        Object.defineProperty(player, i, {
            value: isNaN(this.levelIndex[i]) ? 'LEVEL_' + this.levelIndex[i] : this.levelIndex[i],
            enumerable: false
        });
    }
};
var foo = new Foo();
alert(player[0]); //<-- LEVEL_ONE
alert(foo.levelIndex.FIVE); //<-- 4
for (var i in player) {
    alert(i + ' ' + player[i]); //<-- no output (properties are not enumerable here)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM