在javascript中对knockout.js中的回调正确使用此指针 我是比较有经验的C(在C++ +win32)开发人员之前,我对JavaScript是新手,并且对这个< /C>指针有一个问题。

在javascript中对knockout.js中的回调正确使用此指针 我是比较有经验的C(在C++ +win32)开发人员之前,我对JavaScript是新手,并且对这个< /C>指针有一个问题。,javascript,knockout.js,Javascript,Knockout.js,我使用的是knockout.js,一个名为subscribe的函数接受一个this变量,该变量将在回调函数中设置 var MyObject = function () { this.hello = function () { console.log(this); } } var instance = new MyObject(); 从Win32 days和C#的思维方式来看,在任何回调函数上,我都需要一个包含我的状态的scope对象 在本例中,我使用thisjavascript设置回调范

我使用的是knockout.js,一个名为subscribe的函数接受一个
this
变量,该变量将在回调函数中设置

var MyObject = function () {
  this.hello = function () { console.log(this); }
}

var instance = new MyObject();
从Win32 days和C#的思维方式来看,在任何回调函数上,我都需要一个包含我的状态的scope对象

在本例中,我使用
this
javascript设置回调范围

我的问题是:

  • 现在一切正常(),但我做了什么可怕的事吗

  • 是否有任何原因使用此而不是传递显式 范围变量作为参数(这将使事情更容易理解为 对我来说,这使得工作有点隐蔽)

  • 此的预期用途是什么

  • 从中可以看出:

    subscribe函数接受三个参数:callback是在通知发生时调用的函数,target(可选)在callback函数中定义此参数的值,event(可选;默认为“change”)是要接收通知的事件的名称。下面的示例

    myViewModel.personName.subscribe(function(oldValue) {
        alert("The person's previous name is " + oldValue);
    }, null, "beforeChange");
    
    下面是我的代码片段:

    var computedOptions = createComputedDepdency(viewModel[option.requires.target],option.data);
    viewModel[option.optionsName] = computedOptions;
    
    console.log("making callback scope object for: " + option.optionsName );
    var callbackScope = {
        callbackName: option.optionsName,
        options: computedOptions,
        selectedValue: viewModel[option.selectedName]
    };
    
    // when the list of available options changes, set the selected property to the first option
    computedOptions.subscribe(function () {
        var scope = this;
        console.log("my object: %o", scope);   
        scope.selectedValue(scope.options()[0].sku);
        console.log("in subscribe function for..." + scope.callbackName);
    },callbackScope);
    

    您不应该将作用域和
    这个混用
    这个
    应该模仿经典的oop语言,如java或++,即保留对实例对象的引用。但是,它可以使用
    .apply()
    .call
    在给定上下文上执行任意函数


    关于作用域,您不必做任何事情来将作用域传递给函数,因为外部作用域在函数内部自动可访问。您应该了解闭包-它是javascript最好的部分。

    在javascript中,“this”指调用您的函数的对象。只有在使用“new”关键字的情况下,才能期望它指向当前对象(函数)

    有一种方法可以确保这始终是您所期望的,那就是创建一个变量来存储正确的引用,并使用它来代替此。。。在您的示例中,它将类似于此

    computedOptions = function () {
      var that = this;
    }
    
    computedOptions.subscribe(function () {
        console.log("my object: %o", scope);   
        scope.selectedValue(that.options()[0].sku);
        console.log("in subscribe function for..." + that.callbackName);
    },callbackScope);
    
    不可避免的会比我解释得更好,看看吧

    首先是语义注释:

    函数的范围与
    这个词无关。
    上下文
    与此
    相关。作用域与另一个函数中变量和函数的可访问性有关

    var MyObject = function () {
      this.hello = function () { console.log(this); }
    }
    
    var instance = new MyObject();
    
    当您试图在声明变量的函数之外读取变量时,您就试图访问其作用域之外的变量。因此,您不能这样做,因为var位于从当前位置无法访问的范围内

    现在一切都正常了(如果你感兴趣的话,请在这里全神贯注),但我做了什么可怕的事吗

    如果有效,就没那么可怕了:-)

    是否有任何理由使用它而不是将显式范围变量作为参数传递(这将使事情更容易理解,因为对我来说,这使工作有点隐藏)

    快速阅读:

    在javascript中,
    这个
    的值由函数的调用方式决定

    在某种程度上,这种方法可以将恼人的上下文片段作为参数保存下来:在一个有良好文档记录的库中,
    this
    的使用非常直观。 在其他情况下,我同意当你在没有严格逻辑的情况下不断更改应用程序中的上下文时,它可能会被混淆

    这个的预期用途是什么

    我们应该永远记住javascript是如何以及何时诞生的。它是为了和DOM交互而为浏览器诞生的

    为此,上下文有一种感觉,即基于调用函数的元素的变化

    var MyObject = function () {
      this.hello = function () { console.log(this); }
    }
    
    var instance = new MyObject();
    
    例如:

    var divs = document.getElementsByTagName('DIV');
    
    for(var i = 0; i < divs.length; i++) {
        divs[i].addEventListener('click',_clickHandler);
    }
    
    function _clickHandler() {
        this.innerHTML = "clicked";
    }
    

    不应该
    var scope=this在回调之外。。。?