This指向[一看就懂,包含例子]

我们通常讨论的this指向指的是函数中的this指向,如果this不在函数里面,那就要判断当前环境。node环境this指向空对象{},浏览器环境this指向window(严格模式是undefined)

把对象分成两个部分,对象的名字和对象的数据。对象的名字放在栈中,对象的数据放在堆中。
image.png
image.png
一句话总结this:
this是函数的自有变量,指向了保存在堆中的某个对象的数据

在 JavaScript 中,每个函数都有一个特殊的变量 this。这个变量在函数被调用时被自动创建

这句话非常重要!!!重要的话说三次!!!
这个变量在函数被调用时被自动创建
这个变量在函数被调用时被自动创建
这个变量在函数被调用时被自动创建

所以说this指向跟这个函数是怎么被调用的是很关键的。

确定函数中的this指向谁(哪个对象的数据),完全取决于是如何调用这个函数的
常见的的四种调用形式:

image.png

1.通过new关键字创建的对象,this指向创建的对象即实例。
image.png
2.通过call,apply,bind,this指向我们给到的对象(显示绑定)
image.png
3.函数作为A对象的方法调用,this指向A对象。(隐式绑定)
image.png
4. 以上三种都不是,则指向undefined
image.png

补充:箭头函数没有this
所以箭头函数中的this指向,不要去用上面的方法判断,而是看词法作用域

举个栗子:
image.png
下面逐个解释
1. obj.fun()
fun函数是作为obj对象的方法调用,this指向obj对象,即上述说的第三种情况,所以输出Alice很好理解。
2. obj.funCB()
funCB函数作为obj对象的方法调用,this指向obj对象。funCB下的setTimeout函数中的匿名函数,在调用时不属于前三种情况,所以是第四种undefined。
3. obj.funCBArrow()
funCBArrow函数作为obj对象的方法调用,this指向obj对象。funCBArrow下的setTimeout函数中的匿名箭头函数,由于是箭头函数,箭头函数本身没有this,所以继承自funCBArrow的this,所以指向obj对象。
4. obj.funCBArrow2()()
funCBArrow2函数作为obj对象的方法调用,this指向obj对象。obj.funCBArrow2()返回的是一个匿名函数,obj.funCBArrow2()()调用的就是function(){}匿名函数。调用这个匿名函数不属于前三种情况,所以是第四种undefined,即匿名函数this指向undefined。那么匿名函数下的setTimeout中的箭头函数this继承自匿名函数,所以也指向undefined。
5. obj.funCBArrow3()()
funCBArrow3函数作为obj对象的方法调用,this指向obj对象。obj.funCBArrow3()返回的是一个匿名箭头函数,obj.funCBArrow3()()调用的就是()=>{}匿名箭头函数。由于匿名函数中没有this,所以继承自funCBArrow3的this即指向obj对象,同理setTimeout中的匿名箭头函数的this也继承自上一个匿名箭头函数的this所以指向obj对象。

代码块,可以复制这段js去测试一下

const obj = {
  name: "Alice",
  fun() {
    console.log(`Hello, my name is ${this.name}`);
  },
  funCB() {
    console.log(`Hi, my name is ${this.name}`);
    setTimeout(function () {
      console.log(`Hello, my name is ${this.name}`);
    }, 1000);
  },
  funCBArrow() {
    setTimeout(() => {
      console.log(`Hello, my name is ${this.name}`);
    }, 1000);
  },
  funCBArrow2() {
    return function () {
      setTimeout(() => {
        console.log(`Hello, my name is ${this.name}`);
      }, 1000);
    };
  },
  funCBArrow3() {
    return () => {
      setTimeout(() => {
        console.log(`Hello, my name is ${this.name}`);
      }, 1000);
    };
  },
};

obj.fun();//Hello, my name is Alice
obj.funCB();//Hi, my name is Alice    Hello, my name is undefined
obj.funCBArrow();//Hello, my name is Alice
obj.funCBArrow2()();//Hello, my name is undefined
obj.funCBArrow3()();//Hello, my name is Alice

看看在类中原型上的方法,也是一样的判断方式
image.png

<think>好的,用户想了解JavaScript中this指向规则和修改方法。首先,我需要回忆下相关的知识。JavaScript中的this关键字在不同情况下有不同的指向,常见的有默认绑定、隐式绑定、显式绑定和new绑定。同时,箭头函数没有自己的this,它会继承外层作用域的this值。用户可能在使用对象方法或事件处理时遇到了this指向的问题,或者想了解如何控制this的值。 接下来,我需要整理这些规则。默认绑定下,this指向全局对象(严格模式下是undefined)。隐式绑定中,当函数作为对象方法调用时,this指向该对象。显式绑定通过call、apply或bind方法改变this指向。new绑定时,构造函数中的this指向新创建的实例。箭头函数的this由外层作用域决定,无法通过显式绑定改变。 用户可能遇到的问题包括回调函数中的this丢失,比如在事件处理或定时器中,这时候通常使用箭头函数或bind来固定this。引用中的例子显示,箭头函数在对象方法中的this可能指向window,而通过普通函数返回箭头函数时,this则由外层函数的this决定,这可能让用户困惑。 另外,用户提到的引用3中的例子,使用对象方法时如果对象名改变,内部引用也需要修改,这时候用this可以避免这个问题,但需要正确绑定this。因此,修改this的方法如bind、call、apply以及箭头函数的使用是关键。 需要确保回答结构清晰,分点说明规则和修改方法,结合示例代码帮助理解。同时,引用中的例子要自然地融入解释中,比如引用1和2关于箭头函数的部分,引用3关于this在对象方法中的使用。 可能还需要指出常见误区和注意事项,比如箭头函数不能用作构造函数,call等方法对箭头函数无效等。最后,生成相关问题,帮助用户进步学习,比如不同绑定方式的区别、箭头函数的特性或实际应用中的问题解决。 总结回答结构:先介绍this指向规则,分点说明四种绑定方式,再讲修改方法,如显式绑定和箭头函数,最后常见应用场景和注意事项。确保使用正确的中文术语和LaTeX格式,代码示例用反引号包裹,引用标识放在相关段落末尾。</think>### JavaScript中this指向规则及修改方法 #### this指向的四大规则 1. **默认绑定** 函数独立调用时,非严格模式下`this`指向全局对象(浏览器中为`window`,Node.js中为`global`);严格模式下为`undefined`。 ```javascript function show() { console.log(this); } show(); // 非严格模式输出window;严格模式输出undefined ``` 2. **隐式绑定** 函数作为对象方法调用时,`this`指向调用该方法的对象。 ```javascript const obj = { name: "obj", log: function() { console.log(this.name); } }; obj.log(); // 输出"obj" [^3] ``` 3. **显式绑定** 通过`call`、`apply`或`bind`强制指定`this`指向。 ```javascript function greet() { console.log(this.name); } const person = { name: "Alice" }; greet.call(person); // 输出"Alice" ``` 4. **new绑定** 构造函数中,`this`指向新创建的实例。 ```javascript function Person(name) { this.name = name; } const bob = new Person("Bob"); console.log(bob.name); // 输出"Bob" ``` #### 二、箭头函数的特殊规则 箭头函数没有自己的`this`,其`this`由外层作用域决定,且无法通过显式绑定修改[^1][^2]。 ```javascript const obj = { name: "obj", foo: () => console.log(this.name), bar: function() { return () => console.log(this.name); } }; obj.foo(); // 输出"window"(外层作用域为全局) obj.bar()(); // 输出"obj"(外层作用域的this指向obj) ``` #### 三、修改this指向的方法 1. **`call`和`apply`** 立即执行函数并指定`this`,`call`接受参数列表,`apply`接受数组。 ```javascript function sum(a, b) { return a + b; } sum.call(null, 1, 2); // 3 sum.apply(null, [1, 2]); // 3 ``` 2. **`bind`** 返回个绑定`this`的新函数,适合需要延迟执行时使用。 ```javascript const boundFunc = greet.bind(person); boundFunc(); // 输出"Alice" ``` 3. **箭头函数继承** 在需要固定`this`的场景(如事件回调),用箭头函数避免`this`丢失。 ```javascript const obj = { data: "Hello", init: function() { setTimeout(() => { console.log(this.data); // 输出"Hello"(箭头函数继承init的this) }, 100); } }; ``` #### 四、常见问题与注意事项 - **回调函数中的`this`丢失**: 使用箭头函数或提前绑定`this`(如`bind`)解决。 - **严格模式的影响**: 默认绑定的`this`可能为`undefined`,需显式指定。 - **箭头函数限制**: 不能作为构造函数,且`call`/`apply`对其无效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值