简单了解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 值。
相关推荐
青灯文案16 分钟前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_7482548811 分钟前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.22 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营27 分钟前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood1 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
学代码的小前端1 小时前
0基础学前端-----CSS DAY9
前端·css
joan_851 小时前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
还是大剑师兰特1 小时前
什么是尾调用,使用尾调用有什么好处?
javascript·大剑师·尾调用
m0_748236111 小时前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo6172 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript