JavaScript中调用bind()创建函数时是否会创建Lexical Environment?
JavaScript中
bind()的词法环境与引用持有问题解答 核心结论
- 调用
bind()创建绑定函数时,不会同步创建新的词法环境(Lexical Environment),但会永久持有绑定时传入的预置参数、this值的引用,完全满足你「始终持有literal对象引用、无需重复传参即可访问对象最新状态」的诉求。
行为原理
bind()返回的是ECMAScript规范定义的特殊外来对象——绑定函数(Bound Function),它不依赖普通闭包的词法环境捕获逻辑,而是通过内部插槽直接存储两类数据:
- 绑定的
this值(你的示例中传入的是null) - 绑定时预置的参数列表(你的示例中存储的是
literal变量对应的对象引用)
当你调用绑定函数时,引擎会将内部存储的预置参数,和调用时新传入的参数拼接后传入原函数执行。由于存储的是对象的引用而非对象的快照/深拷贝,因此你对原对象的所有属性修改,都能在调用绑定函数时被读取到。
测试代码行为验证
你的测试逻辑完全符合规范预期,运行结果可以直接印证引用持有的特性:
let literal = { nombre: 'Daniel' }; function parcial(unObjeto, numero) { console.log(unObjeto); } let vinculada = parcial.bind(null, literal); vinculada(); // {nombre: 'Daniel'} literal.nuevapropiedad = 'nuevo valor'; vinculada(); // {nombre: 'Daniel', nuevapropiedad: 'nuevo valor'}
注意:引用持有关系的前提是绑定函数本身处于可达状态、未被垃圾回收。只要绑定函数没有被回收,它内部持有的对象引用就不会丢失,对应对象也不会被GC回收,你无需在每次调用时重新传入对象参数。
常见认知偏差纠正
你之前提到的「bind()会创建词法环境、通过闭包捕获引用」是不准确的:
- 普通闭包的变量捕获,是函数创建时关联所在执行上下文的词法环境,会持有整个词法环境的引用,可能捕获到很多未被实际使用的变量;
bind()生成的绑定函数不会创建新的词法环境,仅存储明确传入的this和预置参数,不会额外捕获外层作用域的其他变量。
内容的提问来源于stack exchange,提问作者user18944870
相关产品推荐
相关产品推荐

