JavaScript中bind作用域解析:boundF1输出原因探究
关于bind作用域与this绑定的困惑解析
嘿,我来帮你把这个问题拆明白——你混淆的核心是变量的词法作用域和函数的this绑定这两个完全独立的规则,咱们一步步拆解:
先看boundF1()的输出:5 1
先回到原函数f1的代码:
function f1() { console.log(x); // 5 console.log(this.x); // 5 }
- 第一个
console.log(x):这里的x是直接引用变量名,它遵循词法作用域规则——JavaScript会先在f1函数内部的作用域查找有没有定义x,没找到就往上一层(这里是全局作用域)找。你全局里执行了this.x=5,在浏览器环境中全局的this就是window对象,所以等价于window.x=5,也就是全局变量x被赋值为5。这个变量查找和this没有任何关系,哪怕你用bind把f1的this改成了{x:1},也不会影响变量x的查找结果,所以这里输出5。 - 第二个
console.log(this.x):这个是访问当前函数执行上下文的this对象上的x属性。f1.bind({x:1})的作用就是把f1调用时的this强制绑定为{x:1}这个对象,所以这里的this.x就是1,输出1。
再看boundF2()的输出:5 5
箭头函数f2的特性是关键:
f2 = () => { console.log(x); // 5 console.log(this.x); // 5 }
- 箭头函数的
this是词法绑定的,也就是说它的this在定义的时候就已经固定了,指向定义它时所在作用域的this(这里是全局的window)。而且箭头函数的this是不可修改的——不管你用bind、call还是apply,都没法改变它的this指向。所以boundF2 = f2.bind({x:1})这行代码完全没用,f2的this依然是全局window。 - 第一个
console.log(x)和之前一样,还是取全局变量的5;第二个console.log(this.x)取的是window.x也就是5,所以输出都是5。
核心规则总结
- 直接写变量名(比如
x):遵循词法作用域链,从当前函数作用域开始向上查找,直到找到变量或抛出错误,和this绑定无关。 - 写
this.x:取决于函数的this绑定规则——普通函数可以通过bind/call/apply、调用方式(比如对象方法调用、new调用)修改this;箭头函数的this是固定的词法this,无法修改。 - 全局作用域中,
this.x = 5在浏览器里等价于声明了全局变量x = 5,所以直接引用x能拿到值。
内容的提问来源于stack exchange,提问作者patrick_corrigan
相关产品推荐
相关产品推荐

