一、 This作用
This
关键字给予了访问当前上下文的能力
- 通过
this
关键字,函数可以访问当前上下文对象的属性和方法
函数中的This
- 函数为一个特殊的对象,每次调用将函数内容
展开至当前上下文
js
var name = "window";
var person1 = {
name: "person1",
foo1: function () {
console.log(this.name);
},
};
person1.foo1();//person1
二、 this的指向
默认绑定
- 默认绑定:当一个函数独立调用,不带任何修饰符的时候
函数为一个特殊的对象,每次调用将函数内容
展开至当前上下文
,因此可类比为window.foo()
js
function foo(){//foo独立调用
console.log(this);//this指代window(全局)
}
foo();
隐式绑定
- 隐式绑定:当函数的引用有上下文对象时(当函数被某个对象所拥有时)
函数为一个特殊的对象,每次调用将函数内容
展开至当前上下文
,因此可类比为obj.foo()
,指向当前上下文
js
var obj = {
a:1,
foo:foo//引用foo
}
function foo(){
console.log(this.a)
}
obj.foo()//1
显式绑定
call()
apply()
bind()
显示的将函数的this
绑定到一个对象上
js
var obj = {
a:1
}
function foo(){
console.log(this.a)
}
foo.call(obj)//1
new绑定
- new绑定:this指向创建出来的实例对象
js
function Person(){
this.name = '小李'
}
let obj = new Person()//{name:小李}
至于为什么可以去看new函数的实现
其他This绑定
- 事件处理程序(
addEventListener
)中的this
- 当一个函数作为事件处理程序被调用时,
this
通常指向触发事件的元素。
- 箭头函数中的
this
- 箭头函数不会绑定自己的
this
,而是继承自外围函数的作用域中的this
。
- 定时器(
setTimeout,setinterval
)的this
this
通常指向window
。
三、箭头函数的This
箭头函数没有this
为了消除
函数的二义性
(构造函数
与直接调用
)
所以箭头函数this指向外层上下文,不能创建属性
箭头函数没有 this
。如果访问 this
,则会从外部获取。
js
let name = "window";
const obj = {
name: "obj",
sayHello: () => {
console.log(this.name);//window
},
};
obj.sayHello();
四、new 操作符的底层原理
new
操作符的实际行为可通过以下步骤模拟:
- 创建空对象
obj
- 将构造函数
this
绑定到obj
- 执行构造函数代码
- 设置
obj.__proto__
指向构造函数原型 - 返回
obj
(除非构造函数返回引用类型)
js
function _new(fn, ...args) {
let obj = {};
obj.__proto__ = fn.prototype;
fn.apply(obj, args);
return obj;
}
五、手写 call 方法实现显式绑定
利用
隐式绑定
实现
js
Function.prototype._call = function(obj, ...arr) {
obj.fn = this
obj.fn(...arr) //隐式绑定
}
Function.prototype._call=function(newThis,...arr){
newThis=newThis||window
let fn=Symbol()
newThis[fn]=this
Object.defineProperty(newThis, fn, { enumerable: false, });
let ans=newThis[fn](...arr)
delete newThis[fn]
return ans
}
let arr = [1];
function fn() {
console.log(this == arr);
}
fn._call(arr);