【问题标题】:Preserving the function's scope when using function.apply(...)使用 function.apply(...) 时保留函数的范围
【发布时间】:2010-09-02 19:23:33
【问题描述】:

考虑以下示例:

var funcToCall = function() {...}.bind(importantScope);

// some time later
var argsToUse = [...];
funcToCall.apply(someScope, argsToUse);

我想保留 funcToCall 的“importantScope”。然而,我需要使用 apply 来应用未知数量的参数。 “应用”要求我提供“someScope”。我不想更改范围,我只想将参数应用于函数并保留其范围。我该怎么做?

【问题讨论】:

  • 是的:它是在 ECMAScript 5 中标准化的。
  • 我正在使用 Prototype 框架。
  • 好吧,这就是我的想法(抱歉删除了评论)。我认为 OP 不是在谈论 JavaScript 1.8.5 - 目前不受任何主要浏览器的支持。
  • 换句话说:是否可以找到函数的作用域对象?
  • @Nick:你自己试过这个简单的例子吗?无论您将什么传递给applyfuncToCall 始终绑定到 importantScope

标签: javascript


【解决方案1】:

您可以将任何旧对象(包括null)作为第一个参数传递给apply() 调用,而this 仍将是importantScope

function f() {
    alert(this.foo);
}

var g = f.bind( { foo: "bar"} );

g(); // Alerts "bar"
g.apply(null, []); // Alerts "bar"

bind 方法创建一个新函数,其中this 值保证是您作为参数传入bind 调用的对象。不管这个新函数如何被调用,this 总是一样的。一个简单的实现看起来像这样(注意指定 ECMAScript 5 的实现,并且在 Prototype 中做的不止这些,但这应该会给你这个想法):

Function.prototype.bind = function(thisValue) {
    var f = this;
    return function() {
        return f.apply(thisValue, arguments);
    };
};

【讨论】:

  • 如果我传递一个对象来应用,那么“任何旧对象”是什么意思,该对象将成为范围。不会吗?在拨打电话时,我不再有权访问“importantScope”
  • @Bears 传递 null 将全局对象绑定为范围。我想“保留”范围,无论它是什么。
  • bind 创建的函数将具有您绑定的this 值,无论它如何调用。查看Function.prototype.bind 的实现可能会有所帮助。我会在我的答案中添加一个。
  • 原始函数和调用其bind方法返回的函数是不同的对象。 “绑定”函数可以看作是一个包装器,它使用绑定调用中指定的this 值调用原始函数,而完全不使用它自己的 this 值。
  • 请注意,Function#bind 的这个轻量级实现没有部分应用程序,因此它不符合 ECMAScript 第五版。 Prototype的实现eg已经完成。
猜你喜欢
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2013-11-04
  • 2020-04-23
  • 1970-01-01
  • 2014-02-24
  • 2016-10-29
相关资源
最近更新 更多