共计 2078 个字符,预计需要花费 6 分钟才能阅读完成。
以下内容来自《你不晓得的 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, 3 console.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
附上集体公众号哦,心愿大家前来骚扰(也会常常写一些随笔来记录生存,毕竟人生漫漫)
正文完
发表至: javascript
2020-07-26