javascript:从回调函数调用对象内部的函数 [英] javascript: call function inside object, from a callback function

查看:54
本文介绍了javascript:从回调函数调用对象内部的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用回调函数中的this"调用对象内部的函数时,会发生错误,指出该方法未定义.我该如何解决这个问题!

when i try to call a function inside the object using "this" from a callback function, an error occur saying that the method is undefined. How can I solve this issue!.

 var object_log = {
    user: "",
    pass: "",
    error_message: "an error occured while connecting",
    init: function(user, pass) {
        this.user = user;
        this.pass = pass;
    },
    login: function() {
        remote_submit(identify, this.success, this.error);
    },
    error: function() {
        alert(this.error_message);
    },
    success: function() {
        alert("success");
    }
};

推荐答案

您需要在回调中使用 .call().apply() 方法来指定调用方法的上下文.

You need to use the .call() or .apply() methods on the callback to specify the context which the method is called upon.

回调方法 remote_submit 不知道 this 将是什么,因此当它调用回调方法时,它们像普通函数一样执行,而不是在对象上.

The callback method remote_submit does not know what this will be anymore and thus when it calls the callback methods they're executed like normal functions not on an object.

您可以通过在出路时包装它们来绑定"您的函数:

You can "Bind" your functions by wrapping them on the way out:

var self = this;
remote_submit(
  identify,
  function() { return self.success.apply(self, arguments); },
  function() { return self.error.apply(self, arguments); }
);

这允许您在匿名函数的闭包中传递上下文,并使用独占的 this 上下文执行回调.

This allows you to pass the context in the closure of the anonymous function and execute the callbacks with an exclusive this context.

看来,在 EMCAScript5+ 中,您可以在函数上使用 bind 来绑定它以用于回调:

It appears that in EMCAScript5+ you can use bind on the function to bind it for use in a callback:

remote_submit(identify, this.success.bind(), this.error.bind())

然而来自 MDN 文档:

绑定函数是最近添加到 ECMA-262,第 5 版;因此,它可能不会出现在所有浏览器中.您可以通过在脚本的开头插入以下代码来部分解决此问题,从而允许在本机不支持它的实现中使用 bind() 的大部分功能.

The bind function is a recent addition to ECMA-262, 5th edition; as such it may not be present in all browsers. You can partially work around this by inserting the following code at the beginning of your scripts, allowing use of much of the functionality of bind() in implementations that do not natively support it.

垫片/polyfill 在这里:

The shim/polyfill is here:

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

<小时>

更新:

要回答您的其他问题,让我们先看看 调用apply 文档并分解它们的工作原理:

To answer your additional question, let's first look at the call and apply documentation and break down how they work:

从根本上说,它们的工作原理是一样的,唯一的区别是它们如何看待自己的论点:

Fundamentally they work the same, the only difference is how they take their arguments:

myfunc.call(target, param1, param2, param3);

将使用 target 作为 this 调用 myfunc(param1, param2, param3).

Will call myfunc(param1, param2, param3) with target as this.

var args = [param1, param2, param3];
myfunc.apply(target, args);

将使用 target 作为 this 调用 myfunc(param1, param2, param3).

Will call myfunc(param1, param2, param3) with target as this.

基本上区别在于 .apply() 接受一个参数数组,其中 call 函数要求您在代码中写入参数.

Basically the difference is that .apply() takes an array of arguments, where the call function requires you to write in the arguments in the code.

接下来,如果我们看看我给你的例子:

Next, if we look at the example i gave you:

function() { return self.success.apply(self, arguments); }

这将返回一个函数,该函数将通过将传递给匿名函数的所有参数(arguments 变量)传递到 apply 函数来调用您的回调.所以:

This returns a function that will call your callback by passing all the arguments (arguments variable) that were passed into the anonymous function, onto the apply function. So:

var a = function() { return self.success.apply(self, arguments); };
a(1,2,3,4);

这将调用 self.success(1,2,3,4)self 作为 this.如果你想用一些特定的东西来增加参数,例如如果你想让 a(1,2,3,4) 调用 self.success(self.test, 1, 2, 3, 4) 那么你必须为 apply 函数提供一个增强数组:

This will call self.success(1,2,3,4) with self as this. If you'd like to augment the arguments with something specific for example if you wanted a(1,2,3,4) to call self.success(self.test, 1, 2, 3, 4) then you'll have to provide an augmented array to the apply function:

var a = function() {
  var args = [self.test];
  for(var i = 0; i < arguments.length; i++) args[] = arguments[i];
  return self.success.apply(self, args);
}

这篇关于javascript:从回调函数调用对象内部的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆