《你不知道的js》——this全面解析

默认绑定

//全局对象用于默认绑定
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

 

posted @ 2018-08-30 08:47  qnlz  阅读(723)  评论(0编辑  收藏  举报