将布尔值传递给jQuery插件的最可靠方法是什么?

3
在构建一个预计传入布尔值的jQuery插件时,最可靠的将输入转换为布尔值的用户友好方式是什么?
更明确地说:我担心有些人可能会传递一个字符串'false'(而不是纯粹的false),因此简单的转换!!option或Boolean(option)将返回“错误”的值(!!'false'为true)。
目前我像这样检查我的变量option:
if (typeof(option) != 'boolean'){
    if (option === 'false'){
        option = false; //fake false
    } else {
        option = !!option; //everything else is converted as truthy / falsy in a standard manner  
    }
}

我在想是否有更优雅、更简洁的方法来实现,或者JavaScript只能这样处理?


1
“当人们试图设计完全防傻的东西时,常见的错误是低估了彻头彻尾的傻瓜的聪明才智。”- 道格拉斯·亚当斯 - j08691
@j08691 好消息是我自己也是个傻瓜,所以准备好迎接很多创意吧 :P 除此之外,将“ fool-proof”替换为“用户友好”。 - m90
4
不要试图“修复”这样的事情。为了照顾无能力的程序员而设计一个API通常是一个非常糟糕的想法。 - Pointy
3个回答

4

我会这样做。

var result = ( userInput === true );

只有当类型为布尔值且值为 true 时,此结果才返回 true。否则,一切都是 false。 不要浪费时间去修复别人的错误。

但是...如果你有很多时间,那就试试这个。

var getBooleanValue = function( userInput ){
    if( !userInput ){
        return false;
    }
    var boolNames = {
        'true':1, 'yes':1,
        'false':0,'no':0,
        'yourMoM':1
    };
    return (userInput in boolNames && !!boolNames[ userInput ])|| ( userInput === true );
};
var tests = [
    [ true, true ],
    [ 'true', true ],
    [ 'yes', true ],

    [ false, false ],
    [ 'false', false ],
    [ 'no', false ]
];
var runTest = function( tests ){
    var i = tests.length;
    while( i-- ){
        if( getBooleanValue(tests[i][0]) !== tests[i][1] ){
            throw new Error( "Test error: getBooleanValues( " + tests[i][0] + ") should return " + tests[i][1] );
        }
    }
};
runTest( tests );

+1 对于适当的测试。-1 对于每次迭代创建临时值的后减量。+1 对于一行代码。 - Tamara Wijsman
var boolNames = { 'true':1, 'yes':1, 'false':0,'no':0, 'yourMoM':this.yes }; 是无效的。您不能在对象字面量中使用 this。否则,解决方案不错。 - Thomas Jones

4
如果您担心此类输入,最可靠的方法是只执行以下操作:
if (typeof(option) != 'boolean')
    console.error('Function X expects a Boolean.');

看看你现在有的解决方案,你没有考虑到01。还有no或者yes呢?

字符串和整数不应该被用作布尔值;因此,没有必要对它们进行解析。


看看高质量/使用的JS框架,他们不这样做。 你为什么要这样做呢?


好的,如果文档中写着“传递一个布尔值”,但有人却传递了他狗的名字,我可以容忍出现错误,所以我只是在寻找一种规避“false”问题的方法 - 除此之外,你说得完全正确。 - m90
@TomWijsman false 不被视为 falsy,而 true 是 truthy 的。用引号括起参数是一个常见的错误。 - Christoph
@Christoph 做出这种错误的程序员需要学习它们是错误的。对于有经验的程序员来说,将非空字符串视为“false”的API确实令人惊讶。 - Pointy
1
@m90:使用您的插件的人需要遵守您在文档中指定的合同;如果他们没有遵守,那么这是他们的错,而不是您的错。Asserts(或错误)可以帮助您捕获此类错误,但您不应该进一步引入未在文档中指定的行为。当然,您可以在文档中枚举您理解的布尔值,但如果您对所有事情都这样考虑,那么您将不得不实现更多的代码并记录更多内容。不要过度思考您的库,否则它可能会以其他方式变得糟糕... - Tamara Wijsman
1
@TomWijsman:“你不应该超出文档规定的行为范围来引入未经说明的行为。”我百分之百地认同,案子结了!感谢您的建议。 - m90
显示剩余3条评论

3
我会做类似这样的事情:
var falsey = ["0", "", "false", "null", "undefined", "NaN"];
var isFalse = false;

for(var i = 0, len = falsey.length; i < len; i++){
    if(options + "" == falsey[i]){
        isFalse = true;
        break;
    }
}

我所做的是将options和falsey值0, "", false, null, undefined, NaN都转换成字符串。
这样可以检测它们,无论它们是什么(类似于将搜索词和比较词都转换为大写字母的技巧)。
由于列表很短,你也可以使用switch case或else if来完成这个任务。

4
滋养那些犯错误的程序员是一个非常糟糕的想法。一个O(n)的for循环和数组查找,真的吗? - Tamara Wijsman
@TomWijsman 是的,也许使用 switch case 或者 else if 会更快。 - ajax333221
1
@ajax333221 或者... 你可以使用一个哈希表,它的平均时间复杂度为 O(1 + n/k)。 - Larry Battle
@LarryBattle 感谢您的评论/回答,两者都+1。我真的学到了很有价值的东西 :) - ajax333221
@LarryBattle 再次问候,我需要您的特殊能力来测试性能,因为我做错了什么。http://jsperf.com/hashtablevsarraylookup - ajax333221
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接