简单了解JavaScript中的this的使用

this的原理

JavaScript 中的 this 是一个特殊的关键字,其值在函数被调用时绑定的。this 的值取决于函数的调用方式,它不是在函数创建时绑定的,而是在运行时基于函数的执行环境动态绑定的。

正如上面所讲,this 是在运行时绑定的,它的上下文取决于函数调用时的各个条件。在 JavaScript 中函数的调用有以下几种方式:

  1. 默认绑定规则
  2. 隐式绑定规则
  3. 显式绑定规则
  4. 构造函数中的 this
  5. 箭头函数中的 this

下面我们按照调用方式不同,分别讨论 this 的含义

默认绑定规则

在默认绑定规则中,独立函数调用时,this指向全局对象; 函数在哪个词法作用域中生效,this指向哪里

例如:

javascript 复制代码
function foo(){
  var a=1;
  console.log(this.a); //此时this指向window
}
foo();//undefined

在上面的例子中foo函数作为独立函数被调用,,因此this指默认绑定到全局(window)对象上,所以this.a的值指向的就是全局变量中a的值,因此输出结果是undefined。

又如:

scss 复制代码
var b=2;
function foo(){
  var b=1;
  function bar(){
    console.log(this.b);//此时this依然指向window
  }
  bar()
}
foo() //在node下为undefined,在浏览器中为2

通过这个例子我们可以知道,即使bar函数定义在了foo函数中,可是barfoo中并没有进行调用,而是在window中进行的调用。因此我们就可以理解独立函数调用时,this指向全局对象的含义了。

隐式绑定规则

隐式绑定规则指的是当函数作为对象的方法被调用时,函数内部的 this 默认指向调用该方法的对象。 例如:

javascript 复制代码
let obj={
  speak: 'hello',
  say: function(){
    console.log(this.speak); // this指向obj
  }
}
obj.say(); //hello

在上面的例子中say函数作为obj对象的方法进行调用,因此函数内部的 this 指向了 obj 对象,可以通过 this.speak 访问 obj 对象中的 speak 属性。 又如下一个例子:

javascript 复制代码
function foo(){
  console.log(this.a); // this指向obj
}

var obj ={
  a: 1,
  foo: foo
}

var obj2={
  a: 2,
  obj: obj
}
obj2.obj.foo();// 1

通过这个例子我们可以看出此时foo函数是作为obj对象的方法进行调用的,尽管obj2调用了obj但是任然输出的是obj中的a,所以当函数被多个对象链式调用时,this指向引用函数的那个对象。

显式绑定规则

显式绑定是通过使用 call, apply, bind 方法,可以手动指定函数执行时的 this 值的一种方法。 例如:

scss 复制代码
function foo(x,y){
  console.log(this.a,x+y);//thi指向obj
}
var obj = {
  a: 1,
};
 foo.call(obj,4,5)  // 1,9
 foo.apply(obj,[4,5]) // 1,9  接收参数需要使用数组接收
 let bar=foo.bind(obj,4,5)() // 1,9  返回一个函数,需要手动调用

通过以上例子,我们可以看到this通过 call, apply, bind 方法,被绑定到了obj上。但是需要注意的是,apply方法它接收的参数是作为一个数组传递,而不是一个一个地传递参数。bind() 方法会创建一个新函数,并将函数中的 this 绑定到指定的对象,但并不会立即执行该函数。而是返回一个绑定了指定上下文的新函数,稍后可以被调用。

构造函数中的 this

当使用 new 关键字调用构造函数时,this 将指向新创建的实例对象。 例如:

ini 复制代码
var a=1;
function foo(){
  this.a=2;
  this.b=3;
}
var obj=new foo(); //new的时候,this指向实例对象
console.log(obj.a,obj.b); //2,3

通过上面的例子我们可以看出,foo是一个构造函数,当使用new创建一个obj实例对象时,this指向了新创建的obj对象,通过 this.athis.b,初始化了 obj 对象的属性。

箭头函数中的 this

在箭头函数中,this 是根据词法作用域来确定的,而不是在函数调用时确定的。箭头函数没有自己的 this,它会捕获函数定义时所处的上下文的 this 值。 例如:

javascript 复制代码
var obj ={
  a:1
}
function foo(){
  var bar=()=>{
    console.log(this)//输出结果为{a:1} 此时this指向obj
  }
  bar()
}
foo.call(obj)//箭头函数里面没有this,所以this指向的是外层的this

通过上面的例子我们可以看出,此时this指向的是obj,因此我们可以得出箭头函数的this指向定义时所在的对象,而不是使用时所在的对象,箭头函数没有this,写在箭头函数中的this也是它外层普通函数的this

总结

通过以上例子,我们可以得出:

  • 默认绑定规则: 当函数独立调用时,this 默认指向全局对象(在浏览器环境下是 window 对象)或者在node模式下是 undefined
  • 隐式绑定规则: 当函数作为对象的方法调用时,this 指向调用该方法的对象。
  • 显式绑定规则: 使用 call, apply, bind 方法,可以手动指定函数执行时的 this 值。
  • 构造函数中的 this 使用 new 关键字调用构造函数时,this 指向新创建的实例对象。
  • 箭头函数中的 this 箭头函数没有自己的 this,它会捕获函数定义时所处的上下文的 this 值。
相关推荐
Asthenia04125 分钟前
Netty编解码器详解与实战
前端
袁煦丞10 分钟前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛1 小时前
vue组件间通信
前端·javascript·vue.js
一笑code1 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员2 小时前
layui时间范围
前端·javascript·layui
NoneCoder2 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19702 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端
烛阴2 小时前
面试必考!一招教你区分JavaScript静态函数和普通函数,快收藏!
前端·javascript
GetcharZp2 小时前
xterm.js 终端神器到底有多强?用了才知道!
前端·后端·go
JiangJiang2 小时前
🚀 React 弹窗还能这样写?手撸一个高质量 Modal 玩起来!
前端·javascript·react.js