Javascript 使用计算的可观测值确定对象范围

Javascript 使用计算的可观测值确定对象范围,javascript,knockout.js,Javascript,Knockout.js,我目前很难使用并希望有人能帮助我确定对象范围 基本上,我有一个目标(为了说明这个问题而简化): 我想引用当前对象的属性,因此执行以下操作: fullName: ko.computed(function(){ return this.firstName() + ' ' + this.lastName(); }, this); ^------- thought 'this' would refer to 'viewModel' 现在,我想这个将引用我的对象viewModel

我目前很难使用并希望有人能帮助我确定对象范围

基本上,我有一个目标(为了说明这个问题而简化):

我想引用当前对象的属性,因此执行以下操作:

fullName: ko.computed(function(){
    return this.firstName() + ' ' + this.lastName();
 }, this);
      ^------- thought 'this' would refer to 'viewModel'
现在,我想
这个
将引用我的对象
viewModel
,但是它引用的是
窗口

因此,会抛出一个错误,说明
未捕获类型错误:未定义的不是函数“
,因为
窗口
没有方法
firstName()
lastName()

HTML:


说到这里,我有以下问题:

  • 为什么
    指的是
    窗口
    ,而不是对象本身
  • 如果不将
    viewModel
    视为一个函数,我如何将其范围限定到对象-
任何帮助都将不胜感激

编辑:


我知道这可以通过将
viewModel
视为一个函数来实现,但是,我想知道是否可以使用对象?
这并不意味着您的viewModel,因为您不在范围内,因为您不在函数内,所以您使用的是对象表示法而不是函数。如果将代码更改为:

var ViewModel = function() {
    this.firstName= ko.observable('John');
    this.lastName= ko.observable('Doe');
    this.fullName= ko.computed(function(){
        // this = window
        // when using -- this.firstName() + ' ' + this.lastName()
        // it will throw Uncaught TypeError: undefined is not a function"

        // return this.firstName() + ' ' + this.lastName();
    }, this);
}

var viewModel = new ViewModel();

然后它应该可以工作,因为您正在创建一个作用域,因此
这个
指的是当前的作用域。

这个
并不意味着您的视图模型,因为您不在作用域内,因为您不在函数内,所以您使用的是对象表示法而不是函数。如果将代码更改为:

var ViewModel = function() {
    this.firstName= ko.observable('John');
    this.lastName= ko.observable('Doe');
    this.fullName= ko.computed(function(){
        // this = window
        // when using -- this.firstName() + ' ' + this.lastName()
        // it will throw Uncaught TypeError: undefined is not a function"

        // return this.firstName() + ' ' + this.lastName();
    }, this);
}

var viewModel = new ViewModel();
然后它应该可以工作,因为您正在创建一个作用域,因此
引用当前作用域。

也可以这样做(演示:)

也可以这样做(演示:)

为了避免混淆这些关键字,使用self是更好的方法。因为self是在函数的闭包中捕获的,所以它在任何嵌套函数(如ko.computed evaluator)中都保持可用和一致。当涉及到事件处理程序时,这个约定甚至更有用,正如您将在许多实时示例中看到的那样

我是从文档本身获取的

为了避免混淆这些关键字,使用self是更好的方法。因为self是在函数的闭包中捕获的,所以它在任何嵌套函数(如ko.computed evaluator)中都保持可用和一致。当涉及到事件处理程序时,这个约定甚至更有用,正如您将在许多实时示例中看到的那样


我是从文档中取的。

吃你的单身蛋糕吧

var viewModel = new function() {
    // Note that the anonymous function is instantiated via new,
    // effectively returning a singleton.
    this.firstName = ko.observable('John');
    this.lastName = ko.observable('Doe');
    this.fullName = ko.computed(function(){
        return this.firstName() + ' ' + this.lastName();
    }, this);
}();

ko.applyBindings(viewModel);

吃你的独生子女蛋糕

var viewModel = new function() {
    // Note that the anonymous function is instantiated via new,
    // effectively returning a singleton.
    this.firstName = ko.observable('John');
    this.lastName = ko.observable('Doe');
    this.fullName = ko.computed(function(){
        return this.firstName() + ' ' + this.lastName();
    }, this);
}();

ko.applyBindings(viewModel);


感谢您抽出时间回答!我知道这可以通过将
viewModel
作为一个函数来实现,但是,我想将这个特定的
viewModel
作为一个单独的对象,这样我觉得对象更合适。ko.computed可以在对象中使用吗?感谢您花时间回答!我知道这可以通过将
viewModel
作为一个函数来实现,但是,我想将这个特定的
viewModel
作为一个单独的对象,这样我觉得对象更合适。ko.computed可以在对象中使用吗?感谢您花时间回答!我知道这可以通过将viewModel作为一个函数来实现,但是,我想将这个特定的viewModel作为一个单例,这样我觉得对象更合适。ko.computed可以在对象中使用吗?Hi@Dom,是-更新了帖子。基本上,您需要一种从ko.computed上下文中获取第一个()和最后一个()值的方法,而不是引用没有函数的
这个
。编辑:事实上,我建议你删除第一个技巧,因为害怕有人会复制它,认为这是个好主意。@JeremyCook,我不会说我是一个淘汰赛专家,所以我很想知道为什么。它是
ko.applyBindings()
位,而不是新的
viewModel()
?请查看此版本的小提琴(),在这里我演示了
窗口。弹出一个提示,提示为true,表示您正在修改
窗口
对象。感谢您抽出时间回答!我知道这可以通过将viewModel作为一个函数来实现,但是,我想将这个特定的viewModel作为一个单例,这样我觉得对象更合适。ko.computed可以在对象中使用吗?Hi@Dom,是-更新了帖子。基本上,您需要一种从ko.computed上下文中获取第一个()和最后一个()值的方法,而不是引用没有函数的
这个
。编辑:事实上,我建议你删除第一个技巧,因为害怕有人会复制它,认为这是个好主意。@JeremyCook,我不会说我是一个淘汰赛专家,所以我很想知道为什么。它是
ko.applyBindings()
位,而不是新的
viewModel()
?请查看此版本的小提琴(),在这里我演示了
窗口。弹出一个提示,提示为true,表示您正在修改
窗口
对象。很抱歉,这没有回答我关于对象内计算的ko.computed的问题。很抱歉,这没有回答我关于对象内计算的ko.computed的问题。谢谢,先生!回答得好!我还添加了其他内容,但这正是我想要的。再次感谢@Dom IIFE将防止任何变量(如
var foo=…
)污染全局名称空间,但它不会改变
。因此,您建议的编辑实际上通过
键修改
窗口
var viewModel = {};

    viewModel.firstName = ko.observable('John');
    viewModel.lastName = ko.observable('Doe');
    viewModel.fullName = ko.computed(function(){
        return viewModel.firstName() + ' ' + viewModel.lastName();
    });
function AppViewModel() {
    var self = this;

    self.firstName = ko.observable('Bob');
    self.lastName = ko.observable('Smith');
    self.fullName = ko.computed(function() {
        return self.firstName() + " " + self.lastName();
    },self);
}
var viewModel = new function() {
    // Note that the anonymous function is instantiated via new,
    // effectively returning a singleton.
    this.firstName = ko.observable('John');
    this.lastName = ko.observable('Doe');
    this.fullName = ko.computed(function(){
        return this.firstName() + ' ' + this.lastName();
    }, this);
}();

ko.applyBindings(viewModel);