javascript中的this

144 阅读2分钟

Hello,各位。前几天在开发的过程中,又遇到了this这个难搞的东西,虽然很多大佬认为这个是javascript语言的败笔,但是没办法,还是得深入了解一下,于是乎,还是总结一下。接下来分析this经常碰到的几种场景。

默认绑定

默认绑定一般就是说直接调用方法,这种情况下,this指向全局对象,例如:

function a(){
   console.log(this);
}

funciton b(){
   a();
}

b(); //window

当然,在对象中调用也是如此,例如:

function a(){
   console.log(this);
}

const b = {
  c(){
     a();
  }
}

b.c(); //window

当然这种情况下,个人认为和静态词法作用域也有显著的关联,这里就不做详述了。 不过要注意'use strict'的问题,如果加了'use strict',那调用方法始终是undefined,例如:

'use strict'
function a(){
   console.log(this);
}

const b = {
  c(){
     a();
  }
}

b.c(); //undefind

隐式绑定

在对象中定义方法,这种还是经常遇到的,但是一般也比较好判断,this指向定义它的对象,例如:

const a = {
 b(){
   console.log(this)
 }
}

a.b(); //{b: ƒ}

当然,对象引用定义的方法也是一样,例如:

function b(){
   console.log(this);
}

const a = {
 b
}

a.b(); //{b: ƒ}

其实这里可以看到已经不受词法作用域的影响了。

new绑定

这个大家肯定轻车熟路,毕竟面试啊要考,更加是写得多。首先是new参数执行的默认操作:

  1. 创建构造函数的原型对象的对象(Object.create(构造函数.prototype)),这部分其实和es6以前知识的有关。
  2. 将构造函数的方法的this指向第一步创建的对象,并执行这个构造函数。
  3. 判断构造函数有木有返回其它参数,有返回就返回这个参数,没有就返回执行完成后的第一步的对象。

浓缩成代码就是:

function create (par = function () { }, ...args) {
  const create = Object.create(par.prototype);
  const res = par.apply(create, args);
  return res instanceof Object ? res : create;
}

所以经过上述步骤,作为构造函数的方法内部的this就必定可以确定。当然es6中的class一样,这里就不展开了。

强制绑定

这个就是各个javascript框架中喜爱的call,bind,apply,了,例如:

 function b(){
    console.log(this);
 }
 const a = { }
 
 b.call(a);
 b.apply(a);
 b.bind(a)()

至于这三个方法的区别,我相信懂滴都懂~。

总结

差不多就这些,笔者主要参照《你不知道的javascript》,这本书在github上中英文都有,大家可以去看看。虽然翻译之后的中文还是那么的大妈之意,晦涩难懂,但是多看几遍还是会眼前一亮的。