默认绑定
//全局对象用于默认绑定
function foo(){
console.log(this.a)
}
var a=2;
foo(); //2
//严格模式下,不能将全局对象用于默认绑定
function foo(){
'use strict';
console.log(this.a)
}
var a=2;
foo(); //TypeError: this is undefined
//在严格模式下调用foo()则不影响默认绑定
function foo(){
console.log(this.a)
}
var a=2;
(function(){
'use strict';
foo();
})(); //2
隐式绑定
//当函数拥有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象
function foo(){
console.log(this.a)
}
var obj={
a:2,
foo:foo
}
obj.foo(); //2
//对象属性链中只有上一层或者最后一层在调用位置中起作用
function foo(){
console.log(this.a)
}
var obj2={
a:42,
foo:foo
}
var obj1={
a:2,
obj2:obj2
}
obj1.obj2.foo(); //42
//this 被隐式绑定的函数会丢失绑定对象,也就是说会应用默认绑定,从而把this绑定到全局对象或者undefined上
function foo(){
console.log(this.a)
}
var obj={
a:2,
foo:foo
}
var bar=obj.foo;
var a="hello";
bar(); //hello
//参数传递其实就是隐式传递,因此我们传入函数是也会被隐式赋值
function foo(){
console.log(this.a)
}
function doFoo(fn){
fn();
}
var obj={
a:2,
foo:foo
}
var bar=obj.foo;
var a="hello";
doFoo(obj.foo) //hello
//回调函数丢失this绑定
function foo(){
console.log(this.a)
}
var obj={
a:2,
foo:foo
}
var a="hello";
setTimeout(obj.foo,100) //hello
显式绑定
//通过foo.call(..),在调用foo时强制把它的this绑定到obj上
function foo(){
console.log(this.a)
}
var obj={
a:2
}
foo.call(obj) //2
//硬绑定
function foo(){
console.log(this.a)
}
var obj={
a:2
}
var bar=function(){
foo.call(obj)
};
bar(); //2
setTimeout(bar,100); //2
//硬绑定的bar 不可能再修改它的this
bar.call(window); //2
//硬绑定典型应用场景:创建一个包裹函数,负责接收参数并返回值
function foo(something){
console.log(this.a,something);
return this.a + something;
}
var obj={
a:2
}
var bar=function(){
return foo.apply(obj,arguments)
}
var b=bar(3); //2 3
console.log(b) //5
//硬绑定典型应用场景:创建一个可以重复使用的辅助函数
function foo(something){
console.log(this.a,something);
return this.a + something;
}
//简单的辅助绑定函数
function bind(fn,obj){
return function(){
return fn.apply(obj,arguments)
}
}
var obj={
a:2
}
var bar=bind(foo,obj);
var b=bar(3); //2 3
console.log(b) //5