# 软绑定和箭头函数的this

> #### 软绑定

硬绑定这种方式可以把this强制绑定到指定的对象，防止函数调用应用默认绑定规则。硬绑定会大大降低函数的灵活性，使用硬绑定之后无法使用应隐式绑定或显式绑定来修改this。

如果可以给默认绑定指定一个全局对象和undefined以外的值，那就可以实现和硬绑定相同的效果，同时保留隐式绑定或者显示绑定修改this的能力。

```
//软绑定代码
if( !Function.prototype.softBind) { 
    Function.prototype.softBind = function(obj){
        var fn = this;
        //捕获所有curried 参数
        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.creat( fn.prototype );
        return bound;
    }
}
```

softBind(...)的原理和ES5内置的bind(..）类似。它会对指定的函数进行封装，首先检查调用时的this，如果this绑定到全局对象或者undefined，那就把指定的默认对象obj绑定到this，否则不会修改this.此外，这段代码还支持可选的柯里化。

> #### 箭头函数this词法

箭头函数不使用this的四种标准规则，而是根据外层（函数或者全局） 作用域来决定this。

```
function foo(){
    //返回一个箭头函数
    return (a)=>{
        //this 继承自 foo()
        console.log( this.a );
    }
}

var obj1 ={
    a : 2
};

var obj2 = {
    a : 3
};

var bar = foo.call( obj1 );
bar.call( obj2 ); //2
```

foo() 内部创建的箭头函数会捕获调用时foo()的 this。由于foo()的this绑定到obj1,bar(引用箭头函数)的this, bar (引用箭头函数)的this也会绑定到obj1，箭头函数的绑定无法被修改。

箭头函数最常用于回调函数，例如事件处理器或者定时器：

```
function foo() {
    setTimeout( ()=>{
        //这里的this在词法上继承自foo()
        console.log( this.a );
    },1000);
}

var obj = {
    a:2
}

foo.call( obj ); //2
```

箭头函数可以像bind()一样确保函数的this被绑定到指定对象，此外，其重要性还体现在它用更常见的词法作用域取代了传统的this机制。实际上，在ES6之前我们就已经在使用一种几乎和箭头函数完全一样的模式。

```
function foo(){
    var self = this;
    setTimeout( fucntion(){
        console.log(self.a)
    },1000)
}

var obj = {
    a : 2
};

foo.call( obj ); //2
```
