2014-10-09 68 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();