以下内容来自《你不晓得的js》读书笔记
this提供了一种更优雅的形式来隐式“传递”一个对象援用,因而能够将API设计得更加简洁并且易于复用。
this与函数的调用地位无关。
一、 this的绑定规定
- 默认绑定
- 隐式绑定
- 显示绑定
- new绑定
1. 默认绑定:即独立函数调用,this会绑定到全局对象上(非严格模式)
function foo(){ console.log(this.a); // 2}var a=2;foo();
留神:对于默认绑定来说,决定this绑定对象的并不是调用地位是否处于严格模式,而是**函数体是否处于严格模式**。如果函数体处于严格模式,this会被绑定到undefined,否则this会被绑定到全局对象。
2. 隐式绑定:调用地位是否有上下文对象,this会被绑定到这个上下文对象。
function foo(){ console.log(this.a);}var obj={ a: 2, foo: foo}obj.foo();// 2
留神:1.对象属性援用链中只有上一层或者说最初一层在调用地位中起作用,即obj.obj2.foo(),那么foo中的this被绑定到了obj2上。2.隐式失落:被隐式绑定的函数会失落绑定对象,也就是说它会利用默认绑定,从而把this绑定到全局对象或者undefined上,取决于是否是严格模式。 (1)将函数赋值给其余变量 (2)函数作为另外一个函数的参数传递进去(严格意义上也属于(1)) function foo(){ console.log(this.a);// 42,产生了隐式失落 } var obj={ a: 2, foo: foo } var a = 42; var foo2=obj.foo; foo2();
3. 显示绑定:能够间接指定this的绑定对象
- call、apply
function foo(){ console.log(this.a);}var obj={ a: 2}foo.call(obj);// 2
以下两种形式可解决失落绑定问题:
- 硬绑定:bind(硬绑定后的this不能再次批改)
function foo(something){ console.log(this.a, something); return this.a + something;}var obj={a: 2};var bar = foo.bind(obj);var b = bar(3);// 2, 3console.log(b);// 5
- API调用的“上下文”:第三方库的许多函数,以及JavaScript语言和宿主环境中许多新的内置函数,都提供了一个可选的参数,通常被称为“上下文”
4. new绑定:在JavaScript中,构造函数只是一些应用new操作符时被调用的一般函数。
- 创立(或者说结构)一个全新的对象。
- 这个新对象会被执行[[Prototype]]连贯。
- 这个新对象会绑定到函数调用的this。
- 如果函数没有返回其余对象,那么new表达式中的函数调用会主动返回这个新对象。
**留神:this绑定的优先级:
new绑定 > 显示绑定 > 隐式绑定 > 默认绑定**
5. 箭头函数:不会应用以上四条规范的绑定规定,依据以后的词法作用域来决定this
二、 绑定例外
- 被疏忽的this:如果你把null或者undefined作为this的绑定对象传入call、apply或者bind,这些值在调用时会被疏忽,理论利用的是默认绑定规定。
- 间接援用:你有可能(无意或者无心地)创立一个函数的“间接援用”,在这种状况下,调用这个函数会利用默认绑定规定。
function foo(){ console.log(this.a);}var a = 2;var o={a: 3, foo:foo};var p={a:4};o.foo();//3(p.foo=o.foo)();// 2// 赋值表达式p.foo = o.foo的返回值是指标函数的援用,因而调用地位是foo()而不是p.foo()或者o.foo()。依据咱们之前说过的,这里会利用默认绑定。
- 软绑定:和硬绑定雷同的成果,同时保留隐式绑定或者显式绑定批改this的能力。
如果this绑定到全局对象或者undefined,那就把指定的默认对象obj绑定到this,否则不会批改this
if(!Function.prototype.softBind){ Function.prototype.softBind=function(obj){ var fn=this; var curried=[].slice.call(arguments, 1); var bound=function(){ return fn.apply( (!this || this === (window || global)) ? obj : this, curried.concat.apply(curried, arguments) ) }; bound.prototype=Object.create(fn.prototype); return bound; }}
心愿大家能继续关注哦,留一些个人信息不便大家找到我哦。知乎 github
附上集体公众号哦,心愿大家前来骚扰(也会常常写一些随笔来记录生存,毕竟人生漫漫)