3

在下面的代码中:

var FilledObjectArray = function() {
    this.filledObject = {};
};

FilledObjectArray.prototype = {
        fill: function() {
            this.filledObject["one"] = 1;
        }
};

var SomeClass = function() {
    this.something = new FilledObjectArray();
};

SomeClass.prototype = {
    showContents: function() {
        this.something.fill();
        for (key in this.something) {
            $("#some-div").append(this.something[key]);
        }
    }   
};

$(document).ready(function() {

    var s = new SomeClass();

    $(".bla").each(function() {
        $(this).click(function() {
            s.showContents();
        });
    });

});

我在 Firebug 控制台中收到此错误:

TypeError: this.filledObject is undefined
this.filledObject["one"] = 1;

我在这里做错了什么?据我了解,对象已正确初始化并且值分配是正确的。我正在 Firefox 18.0.2 版本和 Chrome 25 中对此进行测试。

4

4 回答 4

1

我在现有代码中发现了这个问题并创建了一个建议的解决方案,但是我并不完全清楚您的意图,因此它可能与您的需求略有不同,请根据需要进行修改。

问题

主要问题源于FilledObjectArray对象。这个对象的原型被分配了一个函数fill,然后被分配了一个oneint 类型的属性,值为 1。所以请记住,这个对象有两个属性,一个是函数,一个是 int。

因此,当您执行此代码时...

for (key in this.something) {
    $("#some-div").append(this.something[key]);  //Item 1
}

循环进行了两次迭代,一次用于函数fill,一次用于属性one。问题发生在fill键的迭代上,因为this.something[key]被传递给append(),它不能接受函数,导致 jQuery 触发函数。发生这种情况时,在fill函数的执行上下文中,this分配给#some-div没有filledObject属性的 ,导致抛出 TypeError 。我在下面评论了其中的一些内容:

var FilledObjectArray = function() {
    this.filledObject = {}; //Fill is an object
};

FilledObjectArray.prototype = {
        fill: function() {
            this.filledObject["one"] = 1;
        }
};

var SomeClass = function() {
    this.something = new FilledObjectArray();
};

SomeClass.prototype = {
    showContents: function() {
        this.something.fill();
        for (key in this.something) {
            $("#some-div").append(this.something[key]);  //The fill function is called here
        }
    }   
};

$(document).ready(function() {

    var s = new SomeClass();

    $(".bla").each(function() {
        $(this).click(function() {
            s.showContents();
        });
    });

});

建议的解决方案

var FilledObjectArray = function() {
    this.filledObject = [];
};

FilledObjectArray.prototype.fill = function(){
            console.log(this);
            this.filledObject[0] = 1;
};

var SomeClass = function() {
    this.something = new FilledObjectArray();
};

SomeClass.prototype = {
    showContents: function() {
        this.something.fill();
        for (var x = 0; x < this.something.filledObject.length; x++){
            $("#some-div").append(this.something.filledObject[x]);
        }
    }   
};

$(document).ready(function() {


    var s = new SomeClass();
    $(".bla").each(function() {

        $(this).click(function() {
            s.showContents();
        });
    });
});
于 2013-02-27T11:01:03.603 回答
1

我认为这应该可以解决您的问题

this.something.fill.call(this.something);
于 2013-02-27T10:24:38.680 回答
0

我现在感觉有点笨,但这里是解决这个问题的方法:

SomeClass.prototype = {
    showContents: function() {
        this.something.fill();
        for (key in this.something.filledObject) {
            if (this.something.filledObject.hasOwnProperty(key)) {
                $("#some-div").append(this.something.filledObject[key]);                
            }
        }
    }   
};

我试图访问对象本身(this.something)而不是对象属性(this.something.filledObject)

于 2013-02-27T11:27:39.710 回答
0

我想你在找这个:

for (key in this.something) {
  if(this.something.hasOwnProperty(key)){
    $("#some-div").append(JSON.stringify(this.something[key]));
  }
}

jsbin

您需要使用hasOwnProperty来迭代对象的属性,而无需在继承属性上执行。

于 2013-02-27T11:00:49.360 回答