JavaScript(Underscore.js)扩展功能

时间:2012-09-05 14:21:42

标签: javascript underscore.js

免责声明:(1)我的背景是Java / C#,我上周才开始深入研究JavaScript。 (2)我知道_.mixin()方法。

这不是项目关键,但我在Javascript中无法理解对象继承。

例如,尝试使用_.keyFilter函数(我意识到我可以使用map来实现类似的东西)来扩充underscore.js,以返回满足评估函数的键列表。我可以用_.mixin()方法实现结果:

除了将函数直接放入源代码之外,还有_.mixin()

 _.mixin({ filterKey : function(obj, iterator, context) {
    var results = [];
    if (obj == null) return results;
    _.each(obj, function(value, index, list) {
        if (iterator.call(context, value, index, list)){
            results[results.length] = index;
        }
    });
    return results;
}});

但是,我不确定为什么我不能在我的脚本文件中使用以下内容简单地增加下划线:

_.keyFilter = function(obj, iterator, context) {
        var results = [];
        if (obj == null) return results;
        each(obj, function(value, index, list) {
            if (iterator.call(context, value, index, list)) results[results.length] = index;
        });
        return results;
};

这样做,然后尝试用:

调用它
_.chain(myList).keyFilter(evalFunction);

我得到以下异常:

'Uncaught TypeError: Object [object Object] has no method 'keyFilter' 

注意,当我将它放入underscore.js的源代码时,上述方法确实有效。

然后我尝试在我的脚本文件中使用原型(我仍然没有完全掌握):

var keyFilter = _.prototype.keyFilter = function(obj, iterator, context) {
        var results = [];
        if (obj == null) return results;
        each(obj, function(value, index, list) {
            if (iterator.call(context, value, index, list)) results[results.length] = index;
        });
        return results;
};

但是这引发了同样的例外。 (我认为下面的var被提升到了剧本的顶部,这就是为什么我也尝试了这个以及上面的传递作业)。

非常感谢解释。

2 个答案:

答案 0 :(得分:4)

这不是关于JavaScript的问题,而是关于Underscore的问题,后者倾向于以自己的方式做事。

  • 只需将方法作为属性(即_)添加到_.keyFilter = ...,就像在Java中向类中添加静态方法一样。您正在将方法添加到_对象,但它与_中的其余功能没有任何关系。这是添加新实用程序方法的合理方法,但如果您想使用Underscore的包装和链接功能则不行。

  • 使用.mixin()可以挂钩Underscore的包装和链接架构。这是Underscore特有的 - 它不是JavaScript的一部分。除了编辑源代码之外,这是我所知道的唯一可以利用这些Underscore功能的方法,这些功能主要依赖于Underscore库中的私有方法和变量。

  • 虽然JS支持原型继承,并且每个对象都有prototype属性,但许多开发人员使用其他方法或其他类型的继承。通常不能安全地假设将一个方法添加到看起来像构造函数的prototype实际上是可行的,除非你知道它背后的代码。下划线 对其包装对象使用原型继承,但是以一种扭曲的,有点神奇的方式,我不认为添加方法prototype会产生预期的效果 - 一方面即使它起作用,原型也只在Underscore中用于包装的对象,因此_.keyFilter(...)肯定不起作用。

答案 1 :(得分:0)

我认为这是因为(正如已经说过的)“_.keyFilter =”向_对象添加了一个方法,但使用_(myList)创建了一个非核心对象 - 这就是链的作用 - 这是一个不同的对象。