JS的this指向
this的概念
- this是一个指针型变量,动态指向当前函数的运行环境。
- this永远指向函数的真实调用者,也就是离被调用的函数最近的那个对象(箭头函数除外),如果没有调用者,就指向window对象,例如全局函数,其实window对象就是调用者,只是省略不写。
- 箭头函数没有自己的this,会捕获外层函数作用下的this,如果遇到箭头函数,继续往上找,直到找到普通函数作用域,如果最后没有找到,那就指向window对象。另外箭头函数的this在定义时就会被固定。箭头函数使用call,apply,bind也无法改变this指向。
- 构造函数的this指向实例
- 可以使用call,apply,bind改变this指向,注意箭头函数this指向无法改变。
看几个例子
var obj2 = {
name: 'obj2',
say: function () {
return function() {
console.log(this);
}
}
}
obj2.say()() // window,因为obj2.say()返回的是一个函数,然后这个函数被调用了,调用者是window
var obj2 = {
name: 'obj2',
say: function () {
return () => {
console.log(this);
}
}
}
// 箭头函数在定义时this已经固定了,
// 箭头函数本身没有this对象,会一直往上找作用域的this对象,也就是say函数作用域下的this对象,而say函数由obj2调用,所以this指向obj2
obj2.say()() // obj2
var obj2 = {
name: 'obj2',
say: function () {
this.a = 'a' // this指向obj2
return function() {
return function() {
console.log(this);
}
}
}
}
obj2.say()()() // window,因为obj2.say()()返回一个函数,调用者是window
var obj2 = {
name: 'obj2',
say: function () {
this.a = 'a'
return () => {
return () => {
console.log(this);
}
}
}
}
obj2.say()()() // obj2,箭头函数会往上找外层函数作用域下的this对象,直到找到可用的this对象
var obj2 = {
name: 'obj2',
say: function () {
this.a = 'a'
return () => {
return function() {
console.log(this);
}
}
}
}
obj2.say()()() // window,obj2.say()()是函数,调用者是window
var obj2 = {
name: 'obj2',
say: function () {
this.a = 'a'
return function foo() {
return () => {
console.log(this);
}
}
}
}
obj2.say()()() // window,这里比较复杂
// obj2.say()() == foo,foo的调用者其实就是window,所以foo的this指向是window
// 然后obj2.say()()()执行的箭头函数,箭头函数在定义的时候this已经固定,就是往上找到的foo作用域的this对象,也就是window
var obj2 = {
name: 'obj2',
say: function () {
this.a = 'a'
return obj = {
name: 'foo',
fn() {
console.log(this);
}
}
}
}
obj2.say().fn() // obj,因为obj2.say()返回obj对象,obj是fn的调用者
严格模式下的this
严格模式下,我们对代码的调用必需写上调用者,不得省略
function fn() {
'use strict'
console.log(this);
}
fn() // undefined
window.fn() // window
箭头函数的this
- 箭头函数没有自己的this,会捕获外层函数作用下的this,如果遇到箭头函数,继续往上找,直到找到普通函数作用域,如果最后没有找到,那就指向window对象。另外箭头函数的this在定义时就会被固定。
- 箭头函数使用call,apply,bind也无法改变this指向
- 箭头函数没有arguments对象
var obj = {
fn:()=>{
console.log(this);
}
}
obj.fn() // window,往上找没有找到函数作用域,所以是window
var obj2 = {
name: 'obj2',
say: () => {
return {
name: 'foo',
fn: () => {
console.log(this);
}
}
}
}
obj2.say().fn() // window,往上找先找到say函数作用域,但是say是箭头函数,继续往上找,没找到函数作用域,所以最后是window
var obj2 = {
name: 'obj2',
say() {
return {
name: 'foo',
fn: () => {
console.log(this);
}
}
}
}
obj2.say().fn() // obj2,往上找找到say函数作用域,并且say是普通函数,因为obj2.say()下say的调用者是obj2,所以say作用域的this指向obj2
构造函数的this
构造函数的this指向实例
改变this指向的方法
call
、apply
、bind