首先明确一个概念,即:谁调用这个函数或者方法,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, …}