this
- 默认绑定规则:
console.log(this === window) //true - 隐式绑定规则: 谁调用就指向谁(但会存在隐式丢失和参数复制问题)
- 显示绑定:call,apply,bind
- new绑定
以上四种绑定的优先级:4>3>2>1
父函数有能力决定自函数的this指向
高级函数例如:
arr.foreach(callback)arr.sort(callback)setTimeOut(callback)api决定了this指向(window)
口诀:函数执行时确定this指向,只要是独立调用,就指向window
比如闭包function fn{(return fn1)}(函数执行时被定义并且抛出)时,fn()(),指向window
call,apply,this
//call
//原理:核心点是为传进来的对象context添加fn这个函数属性,
//然后context就可以执行fn这个函数,即改变了this的指向
//把新添加的属性用Symbol声明以免重名
Function.prototype.myCall(context){
context = context || window
const fn = Symbol('tempprops')
context[fn] = this
let args = [...arguments].slice(1)
let result = context[fn](args.join(','))
detele context[fn]
return result
}
//apply
//同apply差不多
Function.prototype.myApply = function(context){
context = context || window
context.fn = this
let res
if(arguments[1]){
res = context.fn(...arguments[1])
}else{
res = context.fn()
}
delete context.fn
return res
}
//bind,这里借助了apply
//bind转换后的函数可以作为构造函数使用。
//此时this应该指向构造函数的实例,而不是bind绑定的第一个参数
Function.prototype.myBind = function(context){
if(typeof this !== 'function'){
throw new TypeError('Error')
}
let _this = this
let args = [...arguments].slice(1)
return function F(){
if(this instanceof F){
return new _this(...args,...arguments)
}
return _this.apply(context,args.concat(...arguments))
}
}