分析 “軟綁定”

一段代碼看了很久也搞不清楚,似懂非懂。

打上斷點,仔細琢磨,終於有一點豁然開朗的感覺。

此處記錄一些不容易想明白的地方,僅供分析用。

        // 檢查調用時的this,如果this綁定到全局對象或者undefined,那就把指定的默認對象obj綁定到this,
        // 否則不會修改this
        // 此段代碼還支持可選的柯里化
        if(!Function.prototype.softBind) {
            Function.prototype.softBind = function(obj) {
                // obj = {name: "obj"}
                var fn = this;     // A處this
                // fn = f foo()
                var curried = [].slice.call(arguments , 1);
                // arguemnts 第一個參數用於綁定this,因此不計入
                var bound = function() {
                    return fn.apply(
                        // B處this
                        // 注意  執行 fooOBJ() 時,此處的this與A處的this不同,
                        // A處this指向foo函數,此處指向window
                        (!this || this === (window || global)) ? 
                        obj : this,
                        curried.concat.apply(curried, arguments)
                    )
                };
                bound.prototype = Object.create(fn.prototype);
                return bound;
            }
        }

        function foo() {
            console.log("name: " + this.name);
        }

        var obj = { name: 'obj' },
            obj2 = { name: 'obj2' },
            obj3 = { name: 'obj3' };

        var fooOBJ = foo.softBind(obj);

        fooOBJ();  // 此時B處this指向window 

        obj2.foo = foo.softBind(obj);
        obj2.foo(); // 此時B處this指向obj2

        fooOBJ.call(obj3);  // 此時B處this指向obj3
        
        setTimeout( obj2.foo, 10); 

        //setTimeout()函數實現和下面的僞代碼類似:
        function setTimeout(fn, delay) {
            // 等待delay毫秒
            fn();
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章