如何在原型设计中引用“自我”

时间:2015-01-23 08:31:35

标签: javascript jquery knockout.js

我有一个带有一些observable和non-observable的对象Task,包括一个属性'ID'。

 Task = function(data){
     var self = this;
     self.ID = data.ID || -1;
     //some more attributes...
     return self;
 }

然后我在对象中写了一个保存原型:

Task.prototype.save = function () {
    if ( this.ID === -1 ){
        //insert into DB
    }
    else {
        // update DB row with ID = this.ID
    }
}

在我的viewModel中,我有一个'Task'的数组,其中'selected'-obsevable指向'Tasks'数组中的当前项。要检查更新,我使用.isDirty-check下载到'selected':

ViewModel = function(){
    var self = this;

    self.Tasks = ko.observableArrays();
    // fill self.Tasks-array with 'new Task(data)'
    // ...some json-code to collect tasks from db and map it to 'Tasks'...

    // initiate 'selected' to be first in array
    self.selected = ko.observable(self.Tasks()[0]);    

    self.selected.subscribe(function (task){
        if( task.isDirty() ){
           task.save();
        }
    });
}

然后从“jQuery(document).ready(function($){...”:

var viewModel = new ViewModel();
ko.applyBindings(viewModel)

看起来干净简单。问题是在实例化viewModel之后订阅命中时,“this”指向我的调用页面(在我的示例中是一个aspx页面)。 我试过用“var self = this”将“this”改为“self”。声明,但无济于事(因为我在我的视图模型中也使用“self”,它仍然引用了aspx页面。

如何让原型指向它自己作为对象?

1 个答案:

答案 0 :(得分:1)

"这"在JavaScript中是一种神奇的东西。

使用" new"初始化对象时关键字,"这个"将是该类创建的对象。这种方式是常用的。你应该使用这种模式的原型,使用" new"关键字。

var MyClass = function () {
    var self = this;
    self.myProp = 123;
}
MyClass.prototype = {
    add: function (num) {
        var self = this;
        return self.myProp + num;
    }
}
var test = new MyClass();
console.log(test.add(111)); // => 234

在" dot"之后调用函数时(。),"这个"将是来电者。

var myCaller = {
    someFunction : function () {
        console.log(this === myCaller); // => true
    }
}
myCaller.someFunction();

如果在没有调用者的情况下调用函数,则默认调用者将是根对象(浏览器中的窗口对象)

var someFunction = function () {
    console.log(this === window); // => true
}
someFunction();

这是一项先进的技术。 当你需要覆盖"这个"时,使用" call"或者"申请"或者" bind"当然,以防这些函数不能被覆盖。他们将第一个参数作为上下文"这个"执行功能时。例如:

var caller = {firstName: "First"};
var someFunction = function () {
    this.lastName = "Last";
    console.log(this === caller);
}
someFunction();                  // ==> false
someFunction.call(caller);       // ==> true
someFunction.apply(caller);      // ==> true
(someFunction.bind(caller))();   // ==> true
new someFunction();              // ==> false

请记住,我们有6种调用函数的方法:使用调用者,不调用者;使用" call"," apply"," bind"覆盖来电者和使用"新"关键字。

在您的情况下,因为您没有提到如何使用上述6种方法之一创建viewModel。所以我假设你没有使用" new",你运行没有调用者的函数。这意味着默认调用者将是窗口对象。请使用" new"。