javascript - 何时在knockoutjs原型(prototype)中使用.bind(this)

标签 javascript knockout.js

我正在学习knockout.js,并在jsfiddle上发现了很多有趣且有用的示例。我正在查看一些knockout.js 示例,其中它使用object.prototype 将方法添加到viewmodel 对象。在某些示例中,它还在 View 模型中定义了一个方法并使用 .bind(this),而在其他示例中它不这样做。所以我不明白什么时候必须将 .bind(this) 与使用原型(prototype)添加的方法一起使用?

例如,this sample使用原型(prototype)向 ViewModel 对象添加一些方法,但它也在 View 模型中定义这些方法,然后使用 .bind(this)。我不明白为什么它需要这样做,因为我发现 another sample它没有在 View 模型中声明相同的方法并使用 .bind(this)。

var ViewModel = function(items) {
    this.selectItem = this.selectItem.bind(this);
    this.acceptItem = this.acceptItem.bind(this);
    this.revertItem = this.revertItem.bind(this);
}
ko.utils.extend(ViewModel.prototype, {
    //select an item and make a copy of it for editing
    selectItem: function(item) {
        this.selectedItem(item);
        this.itemForEditing(new Item(ko.toJS(item)));
    },

    acceptItem: function(item) {
        if (item.errors().length == 0) { //Check if ViewModel has any errors
            alert('Thank you.');
        var selected = this.selectedItem(),
            edited = ko.toJS(this.itemForEditing()); //clean copy of edited

        //apply updates from the edited item to the selected item
        selected.name.update.call(selected, edited);

        //clear selected item
        this.selectedItem(null);
        this.itemForEditing(null);
        }

        else {
            alert('Please check your submission.');
            item.errors.showAllMessages();
        }
    },

    //just throw away the edited item and clear the selected observables
    revertItem: function() {
        this.selectedItem(null);
        this.itemForEditing(null);
    }
});

最佳答案

JavaScript 并不像其他语言那样真正有方法的概念。考虑这个对象:

function Foo() {
    this.foo = 12;
    this.bar = function() {
        console.log('This is', this, 'and this.foo is', this.foo);
    };
}

当您使用 var f = new Foo() 创建新实例时,您可以调用其 bar 属性,该属性恰好是一个函数:

> var f = new Foo()
> f.bar()
This is { foo: 12, bar: [Function] } and this.foo is 12

但是 f.bar 并不是真正的方法,例如 Python 方法,它可以是绑定(bind)的,也可以是未绑定(bind)的。恰好是对象属性的 JavaScript 函数始终未绑定(bind):

> var b = f.bar
> b()
This is Window {...} and this.foo is undefined

当不作为 f 的属性调用时,this 将成为根对象。实际上,调用 f.bar() 会隐式地将 f.barthis 对象设置为 f,例如所以:

> b.call(f)
This is { foo: 12, bar: [Function] } and this.foo is 12

为了使 f.bar 更像绑定(bind)方法,您可以使用 f.bar 绑定(bind)到特定的 this .bind,因此前面的示例按照您的预期工作:

> var b = f.bar.bind(f)
> b()
This is { foo: 12, bar: [Function] } and this.foo is 12

关于javascript - 何时在knockoutjs原型(prototype)中使用.bind(this),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23795400/

相关文章:

JavaScript,检查嵌套对象属性是否为 null/undefined 的优雅方式

javascript - 为什么 javascript 'window.location.hash' 在 ios11 的 WKWebview 中不起作用?

javascript - 在没有 jQuery 的情况下使用顺序选项值填充 knockout 中的下拉列表

knockout.js - 映射插件 - 如何添加 ko.computed 函数

javascript - 将 JSON 从 Rails Controller 加载到 javascript 文件中的 d3 .defer() 函数

javascript - 在循环中传递参数 onclick

javascript - 在不重新加载页面的情况下更改 sIFR "Current Item"颜色

javascript - 如何使用 Knockout.Js 显示筛选列表的结果?

javascript - 如何使用自定义绑定(bind)更新/过滤底层可观察值?

javascript - FirstLetterCaps 类似于 item.toLowerCase()