A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

This的指向 (this是一个记录着一个函数执行上下文的属性)


默认绑定

在无法应用其他规则时,this应用默认绑定,this指向全局对象

在严格模式下(this绑定到undefined)

隐式绑定

当函数应用有上下文的对象时,隐式绑定规则会把当前this绑定到这个上下文对象

例如

foo() {

console.log(this.a)

}

var obj2 = {

a: 2

foo: Foo

}

obj.foo()// 2

对象属性引用链中,只有上一层,或者最后一层在调用位置中起作用

在上面的基础上

var obj1 = {

a: 1

obj2: obj2

}

obj1.obj2.foo() //2  //foof中的this指向obj2

隐式丢失(被隐式绑定的函数,会丢失绑定对象,意味着会应用默认绑定)

function foo() {

console.log(this.a)
}

var obj = {

a:2

foo:foo

}

var baz = obj.foo//函数的别名 >>>>>>这里的baz是不带任何修饰的函数调用,所以应用默认绑定

var a =’global a’

baz()//global a

参数的传递是一种隐式的赋值

function DoFoo(fn) {

fn()

}

dofoo(obj.foo) //global a


回调函数经常会丢失this的绑定,从而变为默认绑定

setTimeOut(obj.foo, 100)

>>>>>>类似

function setTimeOut(fn, delay) {

等待delay毫秒

fn()//这里的this会使用默认绑定

}


显示绑定(利用call和apply方法)

foo() {

console.log(this.a)

}

obj = {

a:1

}

var a=’global a’

foo.call(obj)//this被强制指向obj对象   

foo.apply(obj)//this被强制指向obj对象

//两者的区别就是call和apply的第二个参数不一样,call是很多参数(Foo.call(obj,参数1,参数2.。。。)),apply是一个参数数组(foo.call(obj,【参数1,参数2,......】))

硬绑定(显式绑定的变种)

var baz = foo.call(obj)

baz()//每次调用baz,都会自动将this被强制指向obj

ES5中提供了一个内置方法Function.prototype.bind

var baz = foo.bind(obj)

baz()//每次调用baz,都会自动将this被强制指向obj



new绑定

function foo (a) {

this.a =a

}

var bar =new foo(2)  //构建新对象,将this指向当前新对象

console.log(bar.a)//2


This指向规则的优先级

  • 如果是new绑定,this指向新创建的对象 》》》》最高
  • 是否通过call,applay(显示绑定),this指向当前对象》》》》次之
  • (隐式绑定)函数在某个上下文对象中调用,this指向那个上下文对象》》》》次次之
  • 上面三条规则都没有,应用默认绑定》》》》最次

例外的绑定

如果call,applay传入的对象是null,那么可能应用默认绑定

这种做法,一般是用bind进行柯里化(预先设置以先参数),即将参数传递到函数中去

function foo(a, b) {

console.log(‘a:’+a+’,‘+‘b:’+ b)

}

foo.applay(null, [2,3])//a:2,b:3

var baz = food.bind(2)//实现设置a为2

baz(3))//a:2,b:3


2 个回复

倒序浏览
回复 使用道具 举报
奈斯,很赞
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马