首先明确一个概念,即:谁调用这个函数或者方法,this就指向谁。
通常来讲,this的调用分为以下几种情况:
1、全局this
全局的this就是指window对象。
console.log(this == window)
// 输出:true
2、函数中的this
函数中的this原则上是谁调用函数,函数中的this就指向谁,一般情况下,函数都是挂在window对象上的,即函数中的this也指向window对象。
但是,如果开启了严格模式“use strict”,那么函数中的this将不会指向window对象。
function myfun(){ return this }
console.log(myfun() === window.myfun())
// 输出:true
3、对象方法中的this
this关键字会指向对象本身。
var myobj = {
item: '1',
printItem: function() {
return this.item;
}
}
console.log(myobj.printItem())
// 输出:1
4、构造函数中的this
构造函数中的this指向的是new操作符创建出来的实例。
function myClass(item, content) {
this.item = item;
this.content = content;
this.showThis = function() {
console.log(this)
}
}
var myC1 = new myClass(1, 'content')
myC1.showThis()
// 输出:myClass {item: 1, content: 'content', showThis: ƒ}
5、借来的this
所有的函数都拥有三个方法,可以修改函数中this的指向。
1)call:主动的将函数中的this指向新对象,调用立即执行。
var obj = {
name: "li",
myfun: function (a, b) {
console.log(this.name + `, ${a}, ${b}`);
},
};
var newobj = { name: "wang" };
obj.myfun.call(newobj, 'a', 'b');
// 输出:wang, a, b
2)apply:效果同apply,语法稍有区别。
obj.myfun.apply(newobj, ['a', 'b']);
// 输出:wang, a, b
3)bind:被动式的改变this的指向。
const newMyfun = obj.myfun.bind(newobj);
newMyfun('new a', 'new b')
// 输出:wang, new a, new b
4)call,apply,bind的总结
相同点:(1)都属于“函数对象”上的方法;
(2)第一个参数都是绑定作用域,修改this的指向;
(3)都可以传递参数
不同点:(1)apply,call兼容性更好,适合即刻调用;
(2)bind出自ES5,某些低版本浏览器不支持,一般用在修改回调函数的作用域;
(3)apply传递的参数必须是用数组进行包装,而call和bind则是将要传递的参数一一列出。
6、ES6箭头函数中的this
因为箭头函数没有this,在箭头函数内调用的this始终指向外部,同时也不能使用call,apply,bind等方法来改变this的指向。
es6obj = () => {
console.log(this)
}
es6obj()
// 输出:Window {0: Window, 1: Window, window: Window, self: Window, document: document, name: '', location: Location, …}