【问题标题】:Enclosed functions variable封闭函数变量
【发布时间】:2014-12-04 17:51:41
【问题描述】:

我昨天开始阅读 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/

【问题讨论】:

标签: javascript function object private stampit.js


【解决方案1】:

这里发生的事情与对象如何作为引用传递以及函数返回什么值有关。

在您的代码块中,您有:

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 的任何参数(无)传递给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 的设置然后返回 bar (undefined)。

【讨论】:

    【解决方案2】:

    那么下面的代码是如何工作的,与第一个 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();
    

    【讨论】:

      猜你喜欢
      • 2017-04-21
      • 2012-04-01
      • 1970-01-01
      • 2011-10-13
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      相关资源
      最近更新 更多