0

在不将其绑定到窗口对象的情况下,实现这样的事情的正确方法是什么?

x = function(fn)
{
    foo = 'bar';
    fn();
}

x(function()
{
    console.log(foo) // error happens here
});

在 PHP 中,您可以通过“use”指令进行操作。

$foo = 'bar';
$fn = function() use($foo)
{
    echo $foo; // bar
}

编辑:我改变了一段代码。我想要实现的是,使声明的变量在闭包中可用,而无需将其传递到那里。

foo = 'bar';
console.log(foo) // bar
console.log(window.foo) // bar
console.log(this.foo) // bar

我想用另一个被绑定为“this”的对象来达到同样的效果。

4

5 回答 5

7

好吧,你猜怎么着,JavaScript 有真正的闭包。不像 PHP 那样半生不熟,你必须手动声明要使用的闭包中的所有变量。

此 PHP 代码的等价物:

$foo = 'bar';
$fn = function() use($foo)
{
    echo $foo; // bar
}

这是在JS中:

var foo = 'bar';
var fn = function() {
    console.log(foo);
};

是的。你不是在 PHP 中调用你的函数,我为什么要在 JS 示例中调用它?:-)

顺便说一句,如果你在 JS 控制台中运行这段代码:

var foo = 'bar';
var fn = function() {
    console.log(foo);
};
fn();

您将看到记录了“栏”。证明闭包不需要一些技巧就可以工作。( use)

关于全局变量:$foo变量在您的 PHP 示例中是全局的。它们也在 JS 示例中。如果你想要一个非全局变量,你需要一个本地环境。大多数时候,一个函数。

具有非全局变量的 PHP 示例:

function baz() {
    $foo = 'bar';
    $fn = function() use ($foo) {
        echo $foo;
    };
}

具有非全局变量的 JS 示例:

function baz() {
    var foo = 'bar';
    var fn = function() {
        console.log(foo);
    };
}

最后一点:如果您不使用var在 JS 中声明新变量,则它们是隐含的全局变量。在浏览器中,这意味着它们附加在window对象上。

如果您想比较如何声明全局变量的 PHP/JS:

PHP代码:

$foo; // global
function bar() {
    $_GLOBAL['baz']; // global
    $bin; // local
}

JS代码:

foo; // global
function bar() {
    window.baz; // global
    var bin; // local
    booze; // implied global
}
于 2013-07-10T08:46:42.137 回答
0

在问题的后半部分,您询问有关调用this设置为指定对象的函数的问题。

要调用函数fun设置并将参数设置为 (arg1,arg2,...),请使用thisobjectThatBecomesThis

fun.apply(objectThatBecomesThis, [arg1,arg2,...])

其中第二个参数(可选)是函数的参数数组。

因为第二个参数是一个数组,所以它使用 [] 方括号。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

于 2013-07-10T09:15:57.830 回答
0

答案是,在 PHP 中,您选择包含的内容。在 JS 中,没有办法告诉闭包选择要包含哪些变量。所有词法可用的变量都被括起来。

但是很难说你想要什么,看起来你想隐藏一个闭包变量

唯一的解决方法是隐藏你不想要的变量(通过在内部函数中声明它们)

于 2013-07-10T08:48:54.663 回答
0

如果您想保持窗口对象清洁,那么这可能就是您所需要的。

(function(){

  var foo = 'bar';

  (function(){
      console.log(foo) // bar
  })();

})();

console.log(window.foo); //undefined
于 2013-07-10T08:47:09.833 回答
-1

如果我了解您的需求,您可以这样做:

var closure_variables = new Object();;
closure_variables.foo = 'bar';
window.bar = 'foo'

(function(variables)
{
    console.log(variables.foo) // undefined
    console.log(bar) // foo
})(closure_variables)

或者你甚至可以直接在参数中传递 foo。

于 2013-07-10T08:38:18.467 回答