企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 一、this 的产生   首先this是在**函数**被调用的时候确定的,这一点至关重要,同时被确定的还有arguments。具体来说this是函数被调用时建立的一个绑定,它指向 什么是完全由函数被调用的调用点来决定的。 ### 二、this的用法和指向问题   this 有四种绑定的规则,同时这四种绑定规则对应不同this指向。 1. 隐式绑定 2. 显式绑定 3. new 绑定 4. window 绑定 **隐式绑定** ``` const user = { name: 'Tyler', age: 27, greet() { alert(`Hello, my name is ${this.name}`) } } user.greet() ``` 如果你要调用`user`对象上的`greet`方法,你会用到点号,这就是我们常见的点调用‘隐式绑定’。点左边就是this指向的对象。 **显式绑定**   隐性绑定中有一个致命的限制,就是上下文必须包含我们的函数,如果不仅仅user要用到,address、test对象都要用到,不可能所有对象要一一写进去,这时候我们可以用显示绑定。call apply bind 绑定 ~~~ function foo(x, y ){ console.log(this.a, x, y); } var obj = { a : 10 } foo.call(obj, 1, 3) foo.apply(obj, [1, 3]) //接受一个数组 var newFoo = foo.bind(obj, 1, 3) //创建一个新的函数 newFoo() ~~~ **new 绑定**    new构造函数产生一个新的对象,this绑定的就是新创建的对象。 ~~~jsx function Person(name){ this.name = name; this.say = function(){ return "I am " + this.name; } } var person1 = new Person('nicole'); person1.say(); // "I am nicole" ~~~ 此时的this 指向的就是person1 **window 绑定** 函数调用,如果没有点调用,默认是window调用,所以此时的this 绑定的window。 ~~~ function foo(){ var a = 1 ; console.log(this.a); // 10 } var a = 10; foo(); ~~~ ### 三、使用this注意事项 1、事件绑定中的this,指向的是绑定的dom。 ~~~ document.querySelector('.test').addEventListener('click', function() { console.log(this) }) ~~~ this 指向document.querySelector('.test') 2、setTimeout 中this指向问题,使用setTimeout时需要注意函数this指向问题。下面函数打印出来的name为undefined,因为this指向window, 原因为setTimeout中没有保存obj.sayName的执行环境 ``` var obj = { name: 'hc3001', sayName: function() { console.log(this.name) } } setTimeout(obj.sayName, 1000) //undefined // 利用闭包直接调用obj.sayName() var obj = { name: 'hc3001', sayName: function() { console.log(this.name) } } setTimeout(function() { obj.sayName() }, 1000) // 'hc3001' //用bind解决 setTimeout(obj.sayName.bind(obj), 1000) // 'hc3001' ``` 3、箭头函数的使用,箭头函数调用时不绑定this和arguments,所以this的来源为上一个代码块的this。 ~~~ var x = 11; var obj = { x: 22, say: () => { console.log(this.x); } } obj.say(); //输出的值为11 ~~~ 此时say中的this 指向window而不是指向obj,另外注意箭头函数也是不产生arguments的。