由bind引发的血案

先来看两个例子(浏览器环境,非严格模式下):

var a = 'win';

var obj = {
    a: 'obj',
    say: function() {
        console.log(this.a);
    }
};

obj.say(); // obj

var say = obj.say;
say(); // win

相信上面的例子没有任何悬念的。好了,下面悬念来了:

var a = 'win';

var obj = {
    a: 'obj',
    say: function() {
        console.log(this.a);
    }.bind(this) // 区别在此
};

obj.say(); // ?

var say = obj.say;
say(); // ?

好好想想答案究竟是什么。。。


























答案是:

> win
> win

这表明,我们 bind 的这个 this 实际上是 全局对象window。
这个故事告诉我们:对象中有 function 包裹的 this 才是指向对象本身的哦。。。


你以为这样子就完了吗?Too simple!Naive!放大招来了:

var a = 'win';

var obj = {
    a: 'obj',
    say: function() {
        console.log(this.a);
    }.bind(obj) // 把 this 换成 obj
};

obj.say(); // ?

var say = obj.say;
say(); // ?

好好想想答案究竟是什么。。。


























答案还是:

> win
> win

WTF?!什么鬼?!不是已经死死地 bind 住自身了吗???!!!怎么还是输出全局变量???!!!
这涉及到变量提升问题,上面的代码我们来解析解析:

var a, obj; // 它们都是 undefined

a = 'win';
obj = {
    a: 'obj',
    say: function() {
        console.log(this.a);
    }.bind(obj) // 因此,其实这里 bind 的是 undefined。这样的话内部的 this 就直接指向了全局变量
};

实际上,本来我也想不到是这个原因。后来是通过简单重写 bind 函数来 console 才知道原因:

Function.prototype.bind = function(ctx) {

    console.log(ctx); // 把这个绑定的对象打印出来看看究竟是什么鬼

    var self = this;

    return function() {
        self.apply(ctx, Array.prototype.slice.call(arguments));
    };
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值