- 在全局作用域下this的指向就是window,
let a = 10
console.log(this.a) // 不管是非严格模式还是严格模式都是this
- 函数执行的时候,看前面有没有.如果有点.前面是谁,函数执行的时候,里面的this就是谁,如果没有点.里面的this就是window(非严格模式下),在严格模式下就是undefined
let obj ={
name:10
}
function fn(){
console.log(this)
}
obj.fn() // this输出的是obj
- 给元素绑定事件的时候,当事件触发里面的this就是当前绑定的元素
<div id=ele> ele </div>
let ele.onclick = function(){
console.log(this) // 则是被绑定的元素
}
- 自执行函数的this非严格模式下window,在严格模式下就是undefined
(function(){
console.log(this)
})()
- 回调函数里面this是window
function fn(callback){
console.log(this)
callback()
}
fn(function(){
console.log(this)
})
- 通过类创造的实例,构造函数中的this指的就是当前的实例
function fn(){
this.name = "lili",
this.age = 20
}
var f1 = new fn() // 当前的this就是f1的实例
var f2 = new fn() // 当前的this就是f2的实例
通过call/apply/bind可以更改this的指向
call
function fn(){
console.log(this)
}
let obj = {
name:"lili"
}
fn.call(obj) // 此时this就被指向obj
- 构造函数里面的this就是指向当前的实例,通过this添加的属性名和都属性值都是跟当前的实例添加的
Function.prototype.MyCall = function MyCall(context, ...params) {
/*
思路: 给CONTEXT设置一个属性(例如:xxx,新增的属性不要和原始CONTEXT中的属性冲突(设置Symbol唯一值属性)),
让属性值等于要执行的函数(即:this(fn)),
后面就可以基于CONTEXT.XXX()执行,这样即可以把函数执行了,也让函数中的this改为CONTEXT了....
注意:给原始值加属性不会报错但是也获取不到,保证CONTEXT不是原始值类型
*/
// 为了过滤出传入参数是基本类型的情况
if (context === null) context = window;
if (!/^(object|function)$/.test(typeof context)) context = Object.apply(context)
let _this = this,
key = Symbol('KEY'), // 利用Es6新增属性Symbol生成一个唯一的属性名
result;
// 给参数中新增个uniqueKey属性与调用的函数关联
context[key] = _this;
// 新增完要移除
result = context[key](...params)
// 可以使用Es6新增的API移除对象里面的属性
Reflect.deleteProperty(context, key)
// 把函数执行的结果 return 出去
return result
}
call和apply各自的定义:
-
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
-
call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
call和apply共同之处:
- 都可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象”。
call和apply不同之处:
-
apply:最多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法被传递任何参数。
-
call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法相互调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变this指针。如果没有提供thisObj参数,那么 Global 对象被用作thisObj。
实际上,apply和call的功能是一样的,只是传入的参数列表形式不同。
bind
function MyBind(context,...params){
let _this = this;
return function proxy(...args){
params = params.concat(agrs);
return _this.call(context,...params)
}
}
- bind和call/apply的最大区别就是他不是立即执行而call/apply它时立即就执行了
- bind可以用于点击事件,触发点击事件后才会执行。
最后声明一下:箭头函数中没有this,也没有arguments,但是在箭头函数中用this,会向上级作用域链去找
评论区