2014-10-09 69 views
0

我開始閱讀stampit JS昨日的源代碼,並通過調用應用()可變封閉式功能

instance = fn.apply(instance, arguments) || instance; 

請問這個真正的工作中發現的封裝函數變量的一種有趣的方式在一個對象? 爲什麼下面的代碼行不起作用?

instance = fn.apply(instance, arguments); 

較長的例子:

var createFoo = function() { 
    var foo = {}, 
     fn = function() { 
      var i = 0; 

      this.increment = function() { 
       i++; 
      }; 

      this.get = function() { 
       return i; 
      }; 
     }; 
    foo = fn.apply(foo, arguments) || foo; 
    return foo; 
}, foo = createFoo(); 

test('foo test', function() { 
    foo.increment(); 
    equal(foo.get(), 1, 'pass'); 
}); 

var createBar = function() { 
    var bar = {}, 
     fn = function() { 
      var i = 0; 

      this.increment = function() { 
       i++; 
      }; 

      this.get = function() { 
       return i; 
      }; 
     }; 
    bar = fn.apply(bar, arguments); 
    return bar; 
}, bar = createBar(); 

test('bar tests', function() { 
    bar.increment(); /* undefined */ 
}); 

http://jsfiddle.net/RMh78/59/

+1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply – akonsu 2014-10-09 17:49:20

+1

什麼是你貼在上面的兩行之間有什麼不同? – 2014-10-09 18:06:33

+0

當你有'a || b',這將評估'a'並且在它是「truthy」時返回它,否則它將返回'b'。 – 2014-10-09 18:07:33

回答

2

這是怎麼回事這裏有對象是如何作爲參考傳遞給做,什麼值的函數返回。

在你的代碼塊,你必須:

var createFoo = function() { 
    var foo = {}, 
     fn = function() { 
      var i = 0; 

      this.increment = function() { 
       i++; 
      }; 

      this.get = function() { 
       return i; 
      }; 
     }; 
    foo = fn.apply(foo, arguments) || foo; 
    return foo; 
}, 
foo = createFoo(); 

讓我們打破foo = fn.apply(foo, arguments) || foo;線。

foo已聲明並初始化爲空對象({})。然後在foo函數中將其設置爲this上下文(這就是.apply所做的)。 arguments將通過任何發送到createFoo的參數(none)到fn

因此,當fn.apply運行時,foo對象具有incrementget屬性應用於它。 fn沒有return語句,因此它返回undefined

所以,現在我們有foo = undefined || foo;,並且我們有foo更新了一些屬性。這將foo設置爲自身,然後下一行返回它。

在第二(bar)塊:

var createBar = function() { 
    var bar = {}, 
     fn = function() { 
      var i = 0; 

      this.increment = function() { 
       i++; 
      }; 

      this.get = function() { 
       return i; 
      }; 
     }; 
    bar = fn.apply(bar, arguments); 
    return bar; 
}, 
bar = createBar(); 

您不必fn.apply(bar, arguments)|| bar。因此,fn會運行,它會返回undefinedbar的設置爲barundefined)。

0

那麼下面的代碼是如何工作的,與第一個createFoo函數相比,它有什麼缺點?

var createFoo2 = function() { 
    var foo = {}, 
    fn = function() { 
     var i = 0; 

     this.increment = function() { 
      i++; 
     }; 

     this.get = function() { 
      return i; 
     }; 
    }; 
    fn.apply(foo, arguments); 
    return foo; 
}, 
foo2 = createFoo2();