this
JS中的this究竟是什么呢?指向什么呢? JS中的this的绑定和函数声明位置没有任何关系,只取决于函数调用的方式,即this指向最后调用他的对象
既不指向自身也不指向作用域,仅指向调用的对象
JS如何绑定this指向
默认绑定
function fn2(){
console.log(this) // window
}
function fn3(){
fn2()
console.log(this) // window
}
fn3()
即独立函数调用, fn3()函数调用本质上是window.fn3() ,fn2()虽然是在fn3函数体内调用但是调用本质也是window.fn2(),所以log出2个window
隐式绑定
本质上都是看调用方式来确定this,this就指向最后调用他的对象
如下几个代码实例
1
function fn1(){
console.log(this.name) // qianlon
}
var obj={
var name ='qianlon'
fn1: fn1 // 本质上obj中的fn1只是真实fn1函数的一个引用
}
obj.fn1() //
因为调用fn1()的方式为obj.fn1(),所以fn1中的this即指向obj对象
2
function fn1() {
console.log(this.name) // qianlon----1
}
var obj1 = {
name: 'qianlon----1',
fn1: fn1
}
var obj2 = {
name: 'qianlon----2',
obj1: obj1
}
obj2.obj1.fn1()
obj2调用obj1,obj1再调用fn1(),所以fn1()的this指向obj1
3
易混肴的回调函数(函数作为参数)
function fn1(){
console.log(this.name) // qianlon----global
}
function fn2(fn){
var name ='qianlon----2'
fn()
}
var name = 'qianlon----global'
fn2(fn1)
将fn1作为实参传递给fn,fn也就是fn1的引用,fn()调用方法本质上就是window.fn()即window.fn1(),所以this指向window
JS的内置函数中的回调函数也是如此
function fn1(){
console.log(this.name)
}
setTimeout(fn1,delay)
// 内部如下
setTimeout(fn1,delay){
// 等待delay/ms
fn1()
}
var name ='qianlon----global'
如何手动绑定this
call
fun.call(thisArg, arg1, arg2, ...)
thisArg为需要绑定的对象,arg1,arg2为参数列表
function fn1(){
console.log(this.name) // qianlon----obj
}
var obj={
name: 'qianlon----obj'
}
var name ='qianlon----global'
fn1.call(obj)
通过call让fn1中的this指向obj
apply
fun.apply(thisArg, arg1, arg2, ...)
thisArg为需要绑定的对象,arg1,arg2为参数列表
function fn1(){
console.log(this.name) // qianlon----obj
}
var obj={
name: 'qianlon----obj'
}
var name ='qianlon----global'
fn1.apply(obj)
call apply应用
实现返回一个手动绑定this指向的指定函数
// return 一个手动绑定this指向的指定函数
function bind(fn,obj){
return function(){
return fn.apply(obj,arguments)
}
}
// 字符串拼接
function fn1(something) {
return something + this.name
}
var name = '----global'
var obj = {
name: '----obj'
}
var newFn = bind(fn1, obj) // 获取到指定this的fn1的新函数
var str = newFn('qianlong')
console.log(str);// qianlon----obj
new
- 创建(构造)一个全新对象
- 该对象会执行[[proptype]]连接
- 该对象会绑定到函数调用的this
- 如果函数没有返回其他对象,那么new表达式会自动返回这个新对象
逐步分析以下代码
function fn(a){
this.a =a
}
var bar =new fn(2)
console.log(bar.a)
- new fn(2) 创建了一个全新的对象假设为obj
- 执行[[proptype]]连接
- obj就绑定到fn函数中的this,即fn函数中的this就指向obj
- 由于fn函数没有return一个对象,那么默认就return这个新对象即obj
- 将obj赋值给bar,即bar为obj的引用
this绑定的优先级
这里直接给出结论
new绑定
> 手动绑定
> 隐式绑定
> 默认绑定
注意: new绑定内部实现是用手动绑定(call,apply)实现
思考下一代码
function foo(something){
this.a =something
}
var obj ={}
var bar =foo.bind(obj) // bind为JS提供的内置手动绑定函数,返回一个经过手动绑定的新函数
bar(2)
console.log(obj.a) // 2
var baz =new bar(3)
console.log(obj.a) // 2
console.log(baz.a) // 3
- bar是foo函数通过手动绑定到obj的新函数,即bar函数中的this指向obj
- 所以当执行bar(2)时,obj.a就被修改为2
- 第十行中,new创建了一个新对象,由于new优先级高于手动绑定,所以此时bar函数的this也就指向新对象
- 新对象的a就等于3,并且这个对象赋值给baz
箭头函数
箭头函数的this等于他上一层作用域的this,如果上一层作用域没有this,那么继续向上层寻找直到找到.
注意: this无法改变(手动绑定也不可以)
var name ='qianlon'
function fn1(){
setTimeout(()=>{
console.log(this.name) // qianlon
})
}
fn1()
因为fn1()的调用方式是window.fn1(),所以fn1函数中的this就绑定window,而箭头函数中的this就等于他外一层函数的this就等于window
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!