掌握this指向,让你在变量的拷贝中游刃有余

this 这 this那,this我想 diss你,给我整懵圈了都。最近写代码的时候老用到 this,就自己研究了一下它的各种运用场景,才知道都叫 this能有这么多差别,光 this指向就分五种判断方式,不过关于 this的知识点也都在这五种判定方法里面了。

前言

在JavaScript中,我们使用this的场景大部分都是简单的函数调用,但有部分人也许连为什么要在这添加this.都不知道,它的目的其实就是确保函数内部的this引用能够正确地指向预期的对象,这样说也许有些抽象,此文会详细带你了解这个十分常用而又容易让人忽略的this。

一、this的几种应用场景

1.对象方法中的 this:

js 复制代码
const person = {
    name: 'Alice',
    sayHello: function() {
      console.log(`Hello, my name is ${this.name}`);
    }
  };
  
  person.sayHello(); // 输出:Hello, my name is Alice

2.构造函数中的 this:

js 复制代码
function Person(name) {
    this.name = name;
  }
  
  const apple = new Person('Apple');
  console.log(apple.name); // 输出:Apple
3.箭头函数中的 this:
js 复制代码
const person = {
    name: 'Alice',
    sayHello: () => {
      console.log(`Hello, my name is ${this.name}`);
    }
  };
  
  person.sayHello(); // 输出:Hello, my name is undefined (全局作用域的 `this`)

二、this的指向

这就得拿出this的绑定规则了,用来解释上面几个例子。

核心:

this 的具体值取决于函数的调用方式

绑定规则:

  • 全局作用域中的 this :在全局作用域中,this 通常指向全局对象(在浏览器中是 window,在 Node.js 中是 global)。
  • 函数调用中的 this :当函数作为普通函数调用时,this 的值取决于函数执行的环境。在非严格模式下,this 通常指向全局对象;在严格模式下(使用 'use strict';),this 的值为 undefined
js 复制代码
// 非严格模式下:
function greet() {
    console.log(this === global); // 输出:true
    console.log(this);            // 输出:Object [global]{...}
  }
  
  greet();
js 复制代码
// 严格模式下:
'use strict'
function greet() {
    console.log(this === global); // 输出:false
    console.log(this);            // 输出:undefined
  }
  
  greet();
  • 对象方法调用中的 this :当函数作为对象的方法被调用时,this 的值为该对象。(应用场景中的第一个例子)
  • 构造函数调用中的 this :使用 new 关键字调用构造函数时,this 指向新创建的对象实例。(应用场景中的第二个例子)
  • 箭头函数中的 this :- 箭头函数没有自己的 this,它捕获其外围最近的非箭头函数作用域的 this 值。如果箭头函数在全局作用域中,this 将指向全局对象。(应用场景中的第三个例子)

三、改变this的值

我们可以使用.call(), .apply(), 或 .bind() 方法来显式地改变函数调用中的 this 值。

js 复制代码
var obj = {
    a:1
}
function foo() {
    console.log(this.a);
}
foo.call(obj)    // 输出:1

call的实现原理:先拿到foo,然后将foo引用到obj上,让obj触发foo,最后移除掉obj身上的foo。

结语

如果你了解了this的各种绑定规则,掌握每一个方法中的this指向,就能够轻松地应付它的每一个使用场景了,同时也可以让你在函数里各种变量的拷贝中游刃有余。

相关推荐
鱼樱前端10 分钟前
Vue3+d3-cloud+d3-scale+d3-scale-chromatic实现词云组件
前端·javascript·vue.js
coding随想19 分钟前
JavaScript中的原始值包装类型:让基本类型也能“变身”对象
开发语言·javascript·ecmascript
zhangxingchao22 分钟前
Flutter入门:Flutter开发必备Dart基础
前端
佚名猫32 分钟前
vue3+vite+pnpm项目 使用monaco-editor常见问题
前端·vue3·vite·monacoeditor
满分观测网友z34 分钟前
vue的<router-link>的to里面的query和params的区别
前端·javascript·vue.js
BillKu36 分钟前
Vue3 + TypeSrcipt 防抖、防止重复点击实例
前端·javascript·vue.js
鱼樱前端37 分钟前
Vue3结合three和babylonjs实现3D数字展厅效果
前端·vue.js
Themberfue40 分钟前
Vue ⑥-路由
前端·javascript·vue.js
whatever who cares42 分钟前
React hook之useRef
前端·javascript·react.js