javascript函数意见

时间:2009-07-09 19:09:02

标签: javascript

我写过两个我认为对我正在做的工作非常有用的Array方法。以Ruby的数组方法为模型,这里是我的find和find_all方法。只是想我会把它们扔给社区并得到一些反馈。我是JS编程的新手,所以我可能没有使用足够的防御机制,也许还有一些优化。有什么想法吗?

Array.prototype.find = function(attrs){

    // If an object wasn't passed in return false, maybe throw format exception? 
    // or do primitive type search, but that's not really useful as you're passing in the very value you're looking for
    if (typeof attrs != 'object'){
        return false;
    }else{
        for(var i=0; i < this.length; i++){
            if (typeof this[i] != 'object'){
                return false;
            }else{
                var match = true;
                // Loop through all attributes of the parameters object and test for existence and match
                for(item in attrs){
                    match = match && (this[i][item] && (this[i][item] === attrs[item]) );
                }
                if(match){
                    return this[i];
                }
            }
        }
        // default return if no items found
        return false;
    }   
};

// find_all behaves similarly to find only returns all matched objects
// See ruby's find_all method on arrays
Array.prototype.find_all = function(attrs){
    // If an object wasn't passed in return false, maybe throw format exception? 
    // or do primitive type search, but that's not really useful as you're passing in the very value you're looking for
    if (typeof attrs != 'object'){
        return false;
    }else{
        var valid_items = [];
        for(var i=0; i < this.length; i++){
            if (typeof this[i] != 'object'){
                return false;
            }else{
                var match = true;
                // Loop through all attributes of the parameters object and test for existence and match
                for(item in attrs){
                    match = match && (this[i][item] && (this[i][item] === attrs[item]) );
                }
                if(match){
                    valid_items.push(this[i]);
                }
            }
        }
        return valid_items;
    }   
}

一些例子:

var a={id:1,parent_id:2}
var b={id:2,parent_id:3}
var c={id:3,parent_id:2}
var arr = [a,b,c]

arr.find({parent_id:2}) 
// Object id: 1 parent_id: 2

arr.find_all({parent_id:2})
// [Object id: 1 parent_id: 2, Object id: 3 parent_id: 2 ]

4 个答案:

答案 0 :(得分:3)

您的函数会修改原型Array。有些图书馆觉得这没关系(原型)。其他人反对(jQuery)这种全局修改。

请参阅Prototype网站上的this page。你会明白为什么他们认为修改数组原型是可以的,但前提是你没有使用for ... in循环迭代[编辑:数组(你是对的,你“没有这样做”]。

我实际上更喜欢jQuery的决定,因为你希望你的代码可以重用并且与其他代码一起玩得很好。

另外看一下find算法,如果this [i]具有比attrs更多的属性,只要它们具有共同匹配的属性,它将返回true,但它将是false。

要进行完整的比较,您还必须检查长度,但是对象没有长度属性,因此您必须在一个循环中计算此[i]并分别对其进行长度计算。

编辑:看看你的例子。看起来你知道这两个对象并不完全相同。您确定在搜索{id:1,parent_id:2}}时希望找到{parent_id:2吗?看起来更像是你在询问obj param是否等于对象数组中任何对象的属性子集。你想称之为“发现”吗?这真的是你想要的吗?我认为发现只有在完全相同或者称之为其他东西时才会返回。

编辑2:另一个想法。我肯定会find_all调用find作为其基本机制。这样你就不会重复你的代码,并且你更可能保证找到匹配的东西,find_all会匹配。您不希望在其基础搜索算法之间出现差异。虽然要这样做,你可能不得不重构一下,找回对象的索引而不是对象,这应该不是问题。

答案 1 :(得分:1)

而不是“typeof attrs!='object'”,更常见的是:

if (attrs == null){
    return false;
}

(您也可以使用“if(attrs == undefined)”)。

答案 2 :(得分:1)

除了其他答案所说的,这里有一些关于你的代码的非JS特定事项:

当你有一个返回的if子句时,你不需要else。

if(foo) {
    return false;
}

//other code here

这将使您的代码更具可读性,因为会有更少的缩进/级别来跟踪您的内心。

您的函数不遵循通常的JavaScript命名约定。如果你看看任何JS内置方法,他们使用camelCase而不是underscore_separated。遵循语言惯例总是一个好主意。

答案 3 :(得分:0)

这些对您来说可能是有用的功能,但我会重新考虑将它们添加到Array原型中 - 它们似乎不够通用,因为它们只查找对象属性值。我只是将它们用作实用程序函数(传入数组)或将它们添加到某个实用程序类中。当我想到一个数组查找方法时,我想到了更像这里的例子:http://www.hunlock.com/blogs/Mastering_Javascript_Arrays(但后来我不熟悉Ruby的版本)。