一.this的指向
this的绑定和定义的位置(编写的位置)没有关系
this的绑定和调用方式以及调用的位置有关系
this是在运行时被绑定的
1.绑定规则
-
默认绑定(独立函数调用) foo() 指向window 在严格模式下指向 undefined
-
隐方绑定(通过对象调用) obj.foo() 指向调用对象obj 前提:必须在调用对象内部有一个对函数的引用(比如属性)
-
new绑定(使用new关键字) new foo() 指向新对象
使用new关键字调用函数时,会执行的操作:
- 创建一个全新的对象 - 新对象会被执行prototype连接 - 新对象会绑定在函数调用的this上(this的绑定在这个步骤完成) - 如果函数没有返回其他对象,表达式会返回这个新对象 -
显式绑定(使用call和apply方法) 例:foo.call(obj) 指向obj
4.1 apply()与call()
1.apply foo.apply(obj, ["name",12,1.8]) 第一个参数:绑定this 第二个参数:传入额外的实参,以数组的形式 2.call foo.call(obj, 'name',12,1.28) 第一个参数:绑定this 第二个参数:参数列表:后续的参数已多参数的形式传递,会作为实参 * 区别:第二个参数的格式不同4.2 bind()
作用:创建一个新的绑定函数(怪异函数对象) 例: var bar = foo.bind(obj) bar() // this -> obj bar() // this -> obj 注:foo() // this -> window 用的比较少
2.内置函数绑定
关于内置函数中的this绑定,why的建议是凭经验或者百度谷歌
内置函数:例如setTimeout(),forEach()
3.规则优先级
- 默认绑定最低
- 显式绑定高于隐式绑定
- new绑定高于隐式绑定
- new不可以和apply/call一起使用,故无法比较
- new绑定高于bind优先级
- bind高于apply和call
4.规则之外
1. 显式绑定中,若传入一个unll或nundefined,那么这个显示绑定会被忽略,从而使用默认绑定,此时指向window
2. 箭头函数内没有绑定this,在箭头函数中使用this时会一直在上层作用域寻找,apply和call无法绑定
二.箭头函数
箭头函数是ES6之后增加的一种编写函数的方法
特性:
- 箭头函数不会绑定this,argunments属性
- 箭头函数不能作为构造函数来使用,不能和new一起使用,会抛出错误
默认写法:
foo(()=>{})
优化:
- 如果箭头函数只有一个参数,那么小括号可以省略 foo(item=>{})
- 如果函数体中只有一行执行代码,那么大括号可以省略 foo(item=>console.log(item)),一行代码中不能带return关键字
- 只有一行代码时,这行代码的表达式结果会作为函数的返回值默认返回,可以省去大括号和return
- 如果默认返回值是一个对象,那么这个对象必需加小括号 var newfoo = () => ({nam:'cjddm'})