封闭的函数变量

时间:2014-10-09 17:30:47

标签: javascript function object private stampit.js

我昨天开始阅读stampit js的源代码,并通过调用apply()

找到了一种在函数中包含函数变量的有趣方法。
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/

2 个答案:

答案 0 :(得分: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已声明并初始化为空对象({})。然后将其设置为this函数中的foo上下文(.apply执行的内容)。 arguments会将发送到createFoo的任何args(无)传递给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();

|| bar之后你没有fn.apply(bar, arguments)。那么,会发生fn运行,它返回undefinedbar设置为然后返回barundefined)。

答案 1 :(得分: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();