this的绑定
this的指向是什么东西
- 函数在调用时候,js会默认给this绑定一个值
- this的绑定和定义位置(编写位置)没有关系
- this的绑定和调用方式以及调用位置有关系
- this是在运行的时候被绑定的
绑定规则
-
默认绑定:在严格模式下,this指向就是undefined
//独立调用 function foo(){ console.log(this) } foo()//this指向window let obj = { bar:function foo(){ console.log(this) } } obj.bar()//这样调用不属于独立调用,this指向obj let foo = obj.bar foo()//这样就属于独立调用,this指向的是window -
隐式绑定:通过某个对象进行调用
let obj = { bar:function foo(){ console.log(this) } } obj.bar()//这样调用不属于独立调用,this指向obj -
显示绑定
- apply、call通过很明显的方式指定this的指向
let obj = { name:"obj" } function foo(){ console.log(this) } //这样this的指向就指向了固定的内容 foo.call(obj) foo.call("123") foo.apply(obj) foo.apply("123") //call和apply最大的区别就是,传参的问题 //call第一个参数是明确this的指向,后面的都是参数 foo.call(obj,name,18) //apply第一个参数是明确this的指向,传参的时候要传递一个数组 foo.apply(obj,[name,18])- bind显示绑定,会重新创建一个新的绑定函数
let obj = { name:"obj" } function foo(){ console.log(this) } let bar = foo.bind(obj,'zhangchang',18)//传参方式与call一致 bar()//表面上是独立调用,但是通过bind后,bind的绑定优先级比默认绑定的优先级要高,所有this指向的就是obj -
new绑定
- js中的函数可以当作一个类的构造函数来使用,也就是new关键字
- 当用new关键字调用函数后
- 创建一个全新的对象
- 这个新对象会被执行prototype链接
- 这个新对象会被绑定到this指向上
- 如果函数没有返回其他对象,表达式会返回这个新的对象
function foo(){ console.log(this) } new foo()//指向的就是foo对象
内置函数的绑定思考
- 根据经验进行判断
//这种浏览器内置的函数,我们不能确定是怎么进行调用
setTimeout(function(){
//指向window
//内部显示的指向window
console.log(this)
})
this绑定的优先级比较
new>bind>apply/call>隐式>默认
- 默认绑定的优先级最低
- 显示绑定高于隐式绑定
- new绑定高于隐式的
- new和apply与call使用,但是可以和bind使用
- new优先级高于bind
function foo(){
console.log(this)
}
let obj = {foo:foo}
//this指向肯定是foo
obj.foo()
//这里既有隐式绑定也有显示绑定,显示绑定的优先级会更高
obj.foo.apply("123")
this规则之外
- 总有一些语法,会超出规则之外
- 在显示绑定中,出现了null和undefined
//在非严格模式下指向window
//在严格模式下指向的就是null和undefined
fn.apply(null)
fn.apply(undefined)
-
创建一个函数的间接引用,使用的是默认绑定规则
function foo(){ console.log(this) } let obj1 = { name:"obj1", foo:foo } let obj2 = { name:"obj2" } obj1.foo()//指向obj1 (obj2.foo = obj1.foo)()//指向window,我认为可以当作独立调用
箭头函数 arrow function
function foo(){
}
let foo2 = function(){
}
let foo3 = (name,age)=>{}
- 箭头函数不会绑定this,arguments
- 箭头函数不能作为构造函数来使用(不能和new一起使用,会抛出错误)
//参数只有一个参数,括号可以省略
arr.forEach(item=>{console.log(item)})
//如果函数体中只有一行代码,大括号可以省略
arr.forEach(item=>console.log(item))
//如果只有一行代码,这行代码的结果会作为函数的返回值返回
arr.filter(item => item % 2 ==0)//返回偶数
//如果默认返回值是一个对象,这个对象必须加()
let arrFn = () =>123
console.log(arrFn())//返回123
let arrFn = () =>({name:"zhangcheng "})
console.log(arrFn())//返回{name:"zhangcheng "}
- 箭头函数中的this使用
//箭头函数中没有this,会在自己身上找this,之后会向上查找this
//可以将箭头函数中的this,设想成为自由变量,不看函数被谁调用的,而是看声明的地方向上查找
let bar = ()=>{
console.log(this)
}
bar.apply(123)//指向的依旧是this
//具体使用
//这是工具函数
function request(url,callback){
let res = [1,2,3]
callback(res)
}