首先你要理解下面三句话
1.元素绑定事件,方法中的this是当前操作元素
2.方法名前面是否有点,有点,点前面是谁,this就是谁,没有this是window(严格模式下是undefined)
3.构造函数执行,方法中的this是当前类的一个实例。
下面通过不同的情况来解释一下:
1.全局环境,普通函数调用,普通对象
const obj={a:this}
obj.this===window //true
function fn(){
console.log(this) //window
}
2.构造函数
function a() {
console.log(this)
}
const obj = new a() // this是 a{}
a() // this是 'window'
new出来的对象,this指向了即将new出来的对象。
当做普通函数执行,this指向window。
3.对象方法
const obj = {
x: 0,
foo: function () {
console.log(this)
}
}
obj.foo() // obj
const a = obj.foo
a() //window
作为对象方法,this指向了这个对象。(新对象绑定到函数调用的this)
一旦有变量直接指向了这个方法,this为window.
4.对象方法(特殊情况)
如果在方法里面执行函数,this指向window.
const obj = {
x: 0,
foo: function () {
console.log(this) // obj
function foo1() {
console.log(this) //window
}
foo1()
}
}
obj.foo()
5.构造函数prototype属性
function Fn() {
this.a = 10
let a = 100
}
Fn.prototype.fn = function () {
console.log(this.a) // 10 说明指向了obj这个对象
}
const obj = new Fn()
obj.fn()
原型定义方法的this指向了实例对象。毕竟是通过对象调用的。
6.call ,apply, bind
const obj = {
x: 10
}
function fn() {
console.log(this)
}
fn.call(obj) //obj
fn.apply(obj) //obj
fn.bind(obj)() //obj
this指向传入的对象。
7. 箭头函数
obj = {
a: 10,
c: function () {
b = () => {
console.log(this) //指向obj
}
b()
}
}
obj.c()
在方法中定义函数应该是指向window,但是箭头函数没有自己的this,所以指向上一层作用域中的this.
8.绑定方式
隐士绑定:谁调用方法,this指向谁。
显示绑定:call,bind,apply
new 绑定
优先级问题:new>显示绑定>隐式绑定
如果你上面的都了解通透了,做下面几个this指向问题是非常简单的。
9.this练习题
9.1
9.2
9.3
9.4
9.5
function Foo(){
Foo.a = function(){
console.log(1)
}
this.a = function(){
console.log(2)
}
}
Foo.prototype.a = function(){
console.log(3)
}
Foo.a = function(){
console.log(4)
}
Foo.a()
let obj = new Foo();
obj.a();
Foo.a();
答案解析
9.1 undefined language
obj.prop.fullName //没有undefined this就是window
9.2 window
9.3 0 30
this => myfun =>myfun.a =>0
this => myfun =>myfun.a =>30 设置私有属性的值
9.4 fn object undefined 20 报错 20 NaN
9.4解析看下图
9.5 4 2 1