1

我正在学习 learn.knockoutjs.com教程,我正在自定义绑定教程的第 4 步。有以下 JavaScript:

update: function(element, valueAccessor) {
    // Give the first x stars the "chosen" class, where x <= rating
    var observable = valueAccessor();
    $("span", element).each(function(index) {
        $(this).toggleClass("chosen", index < observable());
    });
}

我已将其翻译为以下 TypeScript:

update: (element, valueAccessor) => {
    var observable = valueAccessor();
    $("span", element).each(index => {
        $(this).toggleClass('chosen', index < observable())
    });
}

这将创建以下内容,其中创建 _this 变量以保留“更新”函数的范围,而不是内部“跨度”函数。

update: function (element, valueAccessor) {
    var _this = this;
    var observable = valueAccessor();
    $("span", element).each(function (index) {
        $(_this).toggleClass('chosen', index < observable());
    });
}

问题出在$(_this). 如何让 TypeScript 给我真正的$(this).

4

3 回答 3

3

好吧,打字稿_this对许多人来说是更直观的,事实上,这样的代码每天会在 Stackoverflow 上导致多次重复:

  update: function() {
     $(elem).click(function(){
          this.save();
     });
  }

this不一样this,因为 jsthis与其他语言的工作方式不同——它对每个函数调用都有单独的绑定。

Typescript 将使上述工作符合许多 js 新手的预期:

  update: function() {
     //this is the object with update, save methods etc
     $(elem).click( () => {
          this.save();  //this is still the object with update, save methods etc
     });
  }

即使使用胖箭头,通常也有一种方法可以引用您想要的内容:

update: function() {
    $(elem).click( (event) => {
        $(event.currentTarget).hide() //same as $(this).hide() with normal function
        this.save(); //Stays intuitive to non-javascripters
    });
}

或者用你的例子:

update: function() {
    $("span", element).each( (index, elem) => {
        $(elem).toggleClass('chosen', index < observable())
        this.save(); //stays intuitive to non-javascripters
    });
}

当然,对于习惯了 JS 行为的有经验的 Javascripter 来说this,它可能不是那么直观。

顺便说一句,我不是 100% 了解打字稿语法...

于 2013-04-15T12:50:23.580 回答
1

答案很简单。不要使用 lambda。

update: (element, valueAccessor) => {
    var observable = valueAccessor();
    $("span", element).each(function (index) {
        $(this).toggleClass('chosen', index < observable())
    });
}

请注意,不同之处在于此代码使用... element).each(function (index)...而不是 lambda

我不明白为什么,所以如果有人可以发布原因,那就太好了。

于 2013-04-15T12:42:35.040 回答
1

Esailija 在这里有一个正确的想法:根本不要$(this)在回调中使用。使用命名参数,您的代码将更加简洁。

作为另一个帮助的例子,考虑这个简单的 jQuery 插件:

// Set a random opacity on each of the elements in a jQuery object
jQuery.fn.randomOpacity = function() {
    return this.each( function() {
        $(this).css({ opacity: Math.random() });
    });
};

哎哟。一段代码可能比这更令人困惑吗?this连续出现在两行,表示完全不同的东西

相反,使用命名参数:

// Set a random opacity on each of the elements in a jQuery object
jQuery.fn.randomOpacity = function() {
    return this.each( function( i, element ) {
        $(element).css({ opacity: Math.random() });
    });
};

这要清楚得多。

于 2013-04-16T07:35:20.250 回答