前端读者 | 嗨,你知道this吗

本文来自 @position_柚子,地址:https://juejin.im/post/5995c7a76fb9a0247a60c407javascript

在平时的代码中,相信你们常常用到 this,但是你真的明白此 this 真的是你认为的 this 吗?今天柚子君总结了一下平时用到的 this 的场景,你们走过路过不要错过啊~java

首先我们先来看一下《JavaScript 高级程序设计》上是怎么说的。windows

this 对象是在运行时基于函数的执行环境绑定的:在全局函数中,this 等于 windows,而当函数被做为某个对象的方法调用时,this 等于那个对象。浏览器

还有一种状况,在《深刻理解 ES6》一书中写道:app

若是箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,且不能经过 call()、apply() 或 bind() 方法来改变 this 的值。函数

首先看一下非箭头函数的状况:post

1、普通函数调用

这是一个普通的函数声明,在这种状况下,this 是指向 window 的:this

var test = '哈哈哈';
function thisHandler() {
    console.log('test:',this.test,'this:',this);
}
thisHandler() // test: 哈哈哈 this: window

其实上面的代码就至关于 window 调用 thisHandler(),因此这时 this 指向 windowprototype

var b = '哈哈哈';
function thisHandler() {
    console.log('b:',this.b,'this:',this);
}
window.thisHandler() // b: 哈哈哈 this: window

2、做为对象的方法调用

看成为对象的方法被调用时,this 这时就指向调用它的对象。设计

var thisHandler = {
  name: "柚子",
  test: function(){
    console.log('my name:',this.name); 
  }
}
thisHandler.test() // my name: 柚子

再来一个栗子:

var thisHandler = {
  name: "柚子",
  fn: {
    name: '芒果',
    test: function() {
       console.log('my name:',this.name); 
    }
  }
}
thisHandler.fn.test() // my name: 芒果

这时 this 指向的是对象 fn 了,因此,关于对象调用这一点明白了吗,若是明白了,那不要紧,接着看下一个强化题:

var name = '柚子'
var thisHandler = {
  name: "芒果",
  fn: {
    name: '糖果',
    test: function(){
      console.log('my name:',this.name); 
    }
  }
}
var testHandler = thisHandler.fn.test
testHandler()

这里是一秒钟分割线

哒哒哒,答对了,这里的 this 指向的 window,那么这是为何呢,哪位小盆友来回答一下。举手:

上面说到了,this 指向的是最后调用它的对象,第一步是赋值给了 testHandler,最后执行的那一句至关于 window.testHandler()。因此这里的 this 指向的是 window。最后输出的就是 my name: 柚子

哒哒哒,真聪明,来闯下一关~

3、构造函数的调用

var name = '柚子'
function Bar() {
  this.name = '芒果'
}

var handlerA = new Bar();
console.log(handlerA.name);  // 芒果
console.log(name) // 柚子

其实要明白为何会是这样一个结果,我们就要来聊聊 new 作了哪些事情。

  • 建立类的实例。这步是把一个空的对象的 __proto__ 属性设置为 Bar.prototype
  • 初始化实例。函数 Bar 被传入参数并调用,关键字 this 被设定为该实例。
  • 返回实例。

弄明白了 new 的工做内容,天然而然的也明白了上面输出的缘由。

Bar() 中的 this 指向对象 handlerA,并非全局对象。

4、apply / call 调用

使用 apply 方法能够改变 this 的指向。若是这个函数处于非严格模式下,则指定为 nullundefined 时会自动指向全局对象(浏览器中就是window对象)。

var name = '芒果';
var thisHandler = {
  name: "柚子",
  test: function(){
    console.log('my name:',this.name); 
  }
};

thisHandler.test(); //  my name: 柚子
thisHandler.test.apply(); // my name: 芒果

4、箭头函数

在《深刻理解 ES6》一书中能够知道箭头函数和普通函数的一个不一样之处就在于 this 的绑定。

箭头函数中没有 this 绑定,必须经过查找做用域链来决定其值。若是箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this;不然,this 的值会被设置为 undefined

var name = '柚子'
var thisHandler = {
  name: '芒果',
  test:() => {
    console.log('my name:',this.name,'this:',this); 
  }
}

thisHandler.test(); // my name: 柚子 this: Window

这时 this 不是指向 thisHandler,而是 Window

关于 this 的使用和体会仍是要在平时运用中理解,先了解其原理,那么在使用的时候就如鱼得水啦。

相关文章
相关标签/搜索