this关键字时是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象

绑定规则

默认绑定

全局环境中定义函数,内部使用this关键字

var name = 'Jenny';function person() { return this.name;}console.log(person());//Jenny

上述调用函数的对象在浏览器中为window,所以this指向window,输出Jenny

隐式绑定

函数可以作为某个对象的方法来调用,此时this就指向这个上级对象

function test() {console.log(this.x);}​var obj = {};obj.x = 1;obj.m = test;​obj.m(); // 1

一个函数中包含多个对象,尽管函数是被最外层的对象调用,this指向的也只是上一级的对象

var o = { a:10, b:{ fn:function(){ console.log(this.a); //undefined } }}o.b.fn();

上述代码中this指向的仍旧是b,b作用域内没有a的定义,所以打印undefined

记住,this指向的是最后调用它的对象

new绑定

通过构造函数new关键字生成一个实例对象,this指向该实例对象

function test() { this.x = 1;}​var obj = new test();obj.x // 1

不过也有特殊情况

当构造函数返回一个简单类型,this仍指向实例对象

但当构造函数返回一个对象时,this指向会改变成返回的对象,如下:

function fn() {this.user = 'xxx';return {}; }var a = new fn(); console.log(a.user); //undefined

手写一个new关键字

function mynew(Func, ...args) { // 1.创建一个新对象 const obj = {} // 2.新对象原型指向构造函数原型对象 obj.__proto__ = Func.prototype // 3.将构建函数的this指向新对象 let result = Func.apply(obj, args) // 4.根据返回值判断 return result instanceof Object ? result : obj}

显示修改

apply()、call()、bind()是函数的方法,作用时改变函数的调用对象,之前已经讲过,apply,call都是临时一次改变,而bind则是返回一个新的函数,指向为传进来的参数。

具体见下方文章链接:

箭头函数

箭头函数在定义时就已经确定了this的指向,且不能通过显示修改的方式改变其this指向

const button = document.getElementById('mngb');button.addEventListener('click', ()=> { console.log(this === window) // true this.innerHTML = 'clicked button'})

如上,该箭头函数被定义时处于全局作用域中,所以this指向window

最后说一下绑定优先级,

new绑定优先级 > 显示绑定优先级 > 隐式绑定优先级 > 默认绑定优先级