当前位置: 首页 > 面试题库 >

使用回调和闭包时在Javascript中保留对“ this”的引用

濮阳旭东
2023-03-14
问题内容

我发现自己将“ this”分配给变量,因此可以轻松地在回调和闭包中使用它。

这是不好的做法吗?有没有更好的方法可以参考原始功能?

这是一个典型的例子。

User.prototype.edit = function(req, res) {

  var self = this,
      db = this.app.db;

  db.User.findById('ABCD', function(err, user)) {

    // I cannot use this.foo(user)
    self.foo(user);
  });
};

User.prototype.foo = function(user) {

};

您通常使用这种方法还是找到了更清洁的解决方案?


问题答案:

处理this回调的主要方法有三种:

1.按照当前操作,创建一个词法范围的变量

此新变量的两个最常见的名称是thatself。我个人更喜欢使用,that因为浏览器具有一个名为self的全局窗口属性,而我的linter会在我遮挡它时抱怨。

function edit(req, res) {
    var that = this,
    db.User.findById('ABCD', function(err, user){
        that.foo(user);
    });
};

这种方法的一个优点是,一旦代码转换为使用代码,that您就可以根据需要添加任意数量的内部回调,并且由于词法作用域,它们都将无缝运行。另一个优点是它非常简单,即使在古老的浏览器上也可以使用。

2.使用.bind()方法。

Javascript函数具有一种.bind()方法,可让您创建具有固定的版本this

function edit(req, res) {
    db.User.findById('ABCD', (function(err, user){
        this.foo(user);
    }).bind(this));
};

当涉及到处理时this,bind方法对于其中一种回调特别有用,在这种回调中,必须添加包装函数会更加冗长:

setTimeout(this.someMethod.bind(this), 500);

var that = this;
setTimeout(function(){ that.doSomething() }, 500);

其主要缺点bind是,如果您具有嵌套的回调,则还需要调用bind它们。此外,IE <=
8和其他一些旧的浏览器
并没有本地实现该bind方法,因此,如果仍然需要支持它们,则可能需要使用某种匀场库。

3.如果需要对函数范围或参数进行更细粒度的控制,请退回到.call()和.apply()

更原始的方式来控制功能参数在Javascript中,包括this,都是.call().apply()方法。它们使您可以使用任何对象作为对象并将其this值作为参数来调用函数apply对于实现可变参数函数特别有用,因为它以数组形式接收参数列表。

例如,这是bind的一个版本,它接收要作为字符串进行绑定的方法。这使我们this仅写下一次而不是两次。

function myBind(obj, funcname){
     return function(/**/){
         return obj[funcname].apply(obj, arguments);
     };
}

setTimeout(myBind(this, 'someMethod'), 500);


 类似资料:
  • 问题内容: 我刚刚开始使用原型JavaScript,并且在弄清楚范围更改时如何从原型函数内部保留对主对象的引用时遇到了麻烦。让我说明一下我的意思(我在这里使用jQuery): 我知道我可以通过在以下内容的开头保留对主对象的引用: 然后用于访问主要对象的属性。但是,当我拥有一大堆原型函数时会发生什么?我是否必须在每个文件的开头都保存对它的引用?似乎应该有一种更清洁的方法。那么这样的情况呢: 在那种情

  • 闭包 函数对象可以通过作用域链关联起来,函数体内的变量可以保存在作用域中,这种特性称“闭包”。 要理解闭包,首先要理解嵌套函数的词法作用域规则:先看下列一段代码: var a = "Tom"; //全局变量 function curr () { var a = "Bob"; //局部变量 function () { return a; } ret

  • 问题内容: 我从javascript对象内部进行了一些Ajax调用。 在onreadystatechange函数内部,它不再引用主对象,因此我无法访问this.foo。我如何在XMLHttpRequest事件中保留对主对象的引用? 问题答案: 最简单的方法通常是将的值存储在局部变量中: 我也怀疑您的标识符确实是构造函数(您正在分配属性)。 如果是这种情况,请不要忘记添加正确的属性(因为您正在替换整

  • 问题内容: 我已经使用JavaScript原型和继承构建了一个大型应用程序。但是我很难组织我的代码。例如,我有一个类轮播,它具有许多类似这样的功能: 我想这样组织我的代码: 但是,这将导致“ this”的值丢失。我可以使用全局实例来跟踪它,但是当类被继承时这会引起问题,例如,在另一个文件中,我有类似的东西可以覆盖父类。 我的继承是这样完成的: 所以我可以做: 有谁知道我该如何处理“ this”值?

  • 本文向大家介绍JavaScript闭包和回调详解,包括了JavaScript闭包和回调详解的使用技巧和注意事项,需要的朋友参考一下 一、闭包  闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 闭包有三个特性: 1.函数嵌套函数; 2.函数内部可以引用外部的参数和变量; 3.参数和变量不会被垃圾回收机制回收。  闭包是指有权访问另一个函数作用

  • 本文向大家介绍教你如何使用firebug调试功能了解javascript闭包和this,包括了教你如何使用firebug调试功能了解javascript闭包和this的使用技巧和注意事项,需要的朋友参考一下 对于跟我一样,自学javascript且没有其他语言学习经验的人来说,一开始的时候,javascript的调试也是一个比较大的难点,很多基础的东西都需要自己去摸索,这个过程是非常苦闷的。 想着