self =这种奇怪的行为在嵌套的viewmodel中与knockout

jko*_*ian 3 javascript knockout.js

我试图抓住knockout.js,但我似乎遇到了一个我不知道的javascript怪癖.

HTML

<ul data-bind="foreach: someList">
    <li data-bind="text: number"></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

使用Javascript

function NestedViewModel(number) {
    self = this;
    self.number = ko.observable(number); 
}

function ViewModel() {
    self = this;
    self.someList = [];

    for (i=0;i<10;i++) {
        var vm = new NestedViewModel(i);
        self.someList.push(vm);
    }

}

ko.applyBindings(new ViewModel());
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,没有任何反应.控制台显示错误:

Uncaught TypeError: Cannot read property 'push' of undefined
Run Code Online (Sandbox Code Playgroud)

当我删除self = this; 来自NestedViewModel的行,我用this.number替换self.number,一切正常!我不清楚javascript在这里做了什么......有人对此有解释吗?一个解决方案?

的jsfiddle

T.J*_*der 6

您需要通过放置var它们来声明这些变量.在没有声明它们的情况下,您正在尝试写入全局self,大多数浏览器都不会让您这样做.(如果不是已经有一个全局调用self的浏览器,那么代码就会成为隐含全局恐怖的牺牲品而且仍然会想要var - 实际上,它会在以后发生i.)

例如:

function NestedViewModel(number) {
    var self = this;
//  ^^^
    self.number = ko.observable(number); 
}

function ViewModel() {
    var self = this;
//  ^^^
    self.someList = [];

    for (var i=0;i<10;i++) {
//       ^^^
        var vm = new NestedViewModel(i);
        self.someList.push(vm);
    }

}

ko.applyBindings(new ViewModel());
Run Code Online (Sandbox Code Playgroud)

(请注意,self引用代码中不需要变量,但我假设您在某些时候使用了闭包,self然后变得有用.)


它没有帮助self,但你可能想要考虑使用严格模式,这会警告你关于未声明的i变量.你可以把它放在"use strict"脚本文件的顶部; 更多在这里.