脑图
1 核心
- 本质上所有函数的调用都是通过某个对象调用的。即使我们通过函数直接调用,它也是通过
window
进行调用的,只不过window
可以省略 - 所有函数内部都有一个变量
this
,调用的方式不同,它就不同。就如同变色龙,靠近不同的物体,自身的颜色就会变成物体的颜色 - 谁调用的函数,函数内部的
this
就是谁
// 我们定义在全局的函数,相当于把函数定义在了window对象上
function aTest(){
console.log(this) // window
console.log('hello world')
}
// 而window可以省略
aTest()
window.aTest()
输出
this
指向的是window
,我们的方法定义在了window
的上面
2 this
的值
总的来说this
的值一共有四种情况,下面一一来说明
2.1 函数直接调用
函数直接调用,相当于通过window.func_name
直接调用,this
指向的是window
function test(){
console.log(this) // window
}
test()
输出
2.2 通过对象调用
通过某个对象调用,this
是调用的那个对象
const obj = {
name:'obj',
test:function(){
console.log(this)
}
}
obj.test()
输出
2.3 通过new
调用
通过构造函数,new
操作符进行调用,this
就是新创建的对象
function Person(name,age){
this.name = name
this.age = age
console.log(this)
}
new Person('Lily',18)//返回this对象
输出
2.3.1 new干了什么
- 创建了一个空对象
- 空对象的原型指向了构造函数的原型
- 让this指向新创建的空对象,并且执行对象的主体(为这个新对象添加属性)
- 判断返回值的类型,如果是值类型就返回新创建的对象,如果是引用类型,就返回这个引用类型的对象
- 如果函数没有返回对象类型Object(包括Functoin, Array, Date, RegExg, Error),那么new表达式中的函数调用将返回该对象的引用
function copyNew(obj, ...args) {
//1.创建了一个空对象
const newObj = {}
//2. 空对象的原型指向了构造函数的prototype
newObj.__proto__ = obj.prototype
//上面的两步可以合为一步
// let newObj=Object.create(obj.prototype)
//3. 将obj的this改为新创建对象
let result = obj.apply(newObj, args)
//判断类里面有返回值吗?返回值是对象吗?如果是的那那就返回类中的返回值,如果不是的话那就返回新创建的对象
return typeof result === 'object' ? result : newObj
}
2.4 通过call()
/apply()
等进行调用
this
是绑定的值 点击
const SunwuKong = {
name:'SunwuKong',
sayName:function(){
console.log(this.name)
}
}
const ZhuBaJie = {
name:'ZhuBaJie'
}
SunwuKong.sayName()
SunwuKong.sayName.call(ZhuBaJie)
输出
2.5 箭头函数
箭头函数没有this,他函数体内的this是外部的this
console.log(this); // window
const fn = () => {
console.log(this);
}
fn() // window