使用bind返回函数是否创建闭包?代码实例相关技术疑问
关于bind与闭包的两个问题解答
一、返回函数时使用bind是否会创建闭包?
简短回答:不一定,得看具体使用场景。
bind()方法的核心是生成一个新的绑定函数(bound function),这个函数会记住两个关键信息:绑定的this指向,以及预先传入的参数(也就是常说的"部分应用"参数)。
而闭包的本质是:函数能够保留对其词法作用域的引用,哪怕外部函数已经执行完毕,该函数依然能访问并操作外部作用域里的变量。
所以,当你用bind()时,如果绑定函数本身(或者你传给bind的参数)引用了外部作用域的变量,且这个引用在外部函数执行完后还存在,那就会形成闭包。反之,如果只是传递基本类型的值,或者没有引用外部作用域的变量,就不会创建闭包。
二、示例分析:调用y()时是否因bind形成对变量x的闭包?
先看你给出的代码:
function inner(x){ return x; } function outer(fn){ var x = 'I just made a closure!!!' return fn.bind(this, x) } var y = outer(inner) y() // 返回 'I just made a closure!!!'
你的困惑点在于:y()能拿到outer内部的x,但x属于outer的作用域,这看起来像是闭包?但其实这并不是闭包,原因如下:
- 当
outer执行到fn.bind(this, x)时,x是字符串(基本类型),此时bind()会把x的当前值复制一份,作为绑定函数y的预设参数保存起来——它并没有保留对outer作用域中x变量的引用。 - 我们可以用一段代码验证这一点:如果在
bind之后修改outer里的x,y()返回的依然是bind时的旧值:function inner(x){ return x; } function outer(fn){ var x = 'I just made a closure!!!' var boundFn = fn.bind(this, x); x = 'Oops, I changed x!'; // 修改x的值 return boundFn; } var y = outer(inner) y() // 依然返回 'I just made a closure!!!' - 闭包的核心是保留对作用域的引用,而非保存值。如果这里是闭包,修改
x后y()应该返回新值,但实际并没有——这说明y并没有持有对outer作用域的引用,只是保存了x的初始值。
那什么时候用bind会形成闭包呢?比如下面的场景:
function outer(){ var count = 0; // 匿名函数引用了outer作用域的count,bind后返回这个函数 return function(){ count++; console.log(count); }.bind(this); } var counter = outer(); counter(); // 1 counter(); // 2
这里的绑定函数counter就形成了闭包,因为它引用了outer作用域的count变量,哪怕outer执行完毕,counter依然能访问并修改count。
内容的提问来源于stack exchange,提问作者Alon Parag
相关产品推荐
相关产品推荐

