为什么我会从javascript函数返回一个命名函数(对象)?

时间:2013-12-18 06:45:35

标签: javascript object

也许我错过了一些明显的东西...我刚刚开始使用 JavaScript ,在浏览一篇关于使用Jasmine进行单元测试JavaScript的文章时,我遇到了这段代码:

function Convert(number, fromUnit) {  
    var conversions = {  
            distance : {  
                meters : 1,  
                cm     : 0.01,  
                feet   : 0.3048,  
                inches : 0.0254,  
                yards  : 0.9144  
            },  
            volume : {  
                litres : 1,  
                gallons: 3.785411784,  
                cups   : 0.236588236   
            }  
        },  
        betweenUnit = false,  
        type, unit;  

    for (type in conversions) {  
        if (conversions[type]) {  
            if ( (unit = conversions[type][fromUnit]) ) {  
                betweenUnit = number * unit * 1000;  
            }  
        }  
    }  

    return {  
        to : function (toUnit) {  
            if (betweenUnit) {  
                for (type in conversions) {  
                    if (conversions.hasOwnProperty(type)) {  
                        if ( (unit = conversions[type][toUnit]) ) {  
                            return fix(betweenUnit / (unit * 1000));  
                        }  
                    }  
                }  
                throw new Error("unrecognized to-unit");  
            } else {  
                throw new Error("unrecognized from-unit");  
            }    

            function fix (num) {  
                return parseFloat( num.toFixed(2) );  
            }  
        }  
    };  
}  

令我困惑的是为什么/如何使用它,以及它的原因是什么。它出现来返回一个对象,这是一个带标签的函数(根据JavaScript命名约定的方法),在创建时不会被调用或返回。

在考虑了这个问题并在chrome dev工具中运行之后,我发现它被称为Convert,其大写为C,它可能会被用作与{{1}一起使用的构造函数(再次,根据JavaScript命名约定)所以我可能会创建一个对象,如:
 new然后将其用作var tenFeet = new Convert(10, 'feet');

这仍然没有意义,因为我不会调用该对象(读取:类)tenFeet.to('cm');,因为它不会转换。我会调用Convert方法to,并可能将convertTo命名为Convert或其他内容。

  1. 这是一个错误的命名错误的代码,我只是根深蒂固地使用传统的OO和“正式”语言,还是我错过了一些基本的东西?
  2. 何时/何地/为什么我会使用上述内容:“返回标记方法”来自JavaScript中的对象?
  3. 使用相同的方法增强Measurement的原型可能无法实现同样的效果吗?
  4. 干杯,并提前感谢。

2 个答案:

答案 0 :(得分:1)

这是一些人喜欢的“读起来像一句话”的范例:

Convert(10, 'meters').to('feet') === 32.81
// Convert 10 meters to feet

你是对的,这个函数违反了常见的命名约定,但你可以猜测它不应该用new关键字创建,因为在this中没有对{{1}}的引用。功能体。

通过适当的文档可以避免这个问题。

答案 1 :(得分:0)

Blender正确地回答了这个问题,但是为了防止其他人偶然发现页面,这里有更多关于正在发生的事情的信息。

来自更“正式”的语言,我想我在返回语句中遇到to的“标签”外观问题。

来自MDN on Label

  

<强>摘要
  提供带有标识符的语句,您可以使用break或continue语句引用该标识符。

     

例如,您可以使用标签来标识循环,然后使用break或continue语句来指示程序是应该中断循环还是继续执行循环。

     

<强>语法
  label:声明

请注意,如果您正在创建对象,则语法类似。例如:

  

人= {姓: “John” 的名字: “Doe的”,年龄:50,眼睛颜色: “蓝”};

这将导致对象看起来像:

  

object {firstname:“John”,姓:“Doe”,年龄:50,eyecolor:“blue”}

另一个注意事项是,如果你正在创建一个数组,你只需使用逗号,如下所示:

person=["John","Doe",50,"blue"];

这将给出一个类似于:

的数组
["John", "Doe", 50, "blue"]

习惯JavaScript语法和逻辑需要一些时间,但在我的示例中真正发生的是该函数返回一个对象,该对象上定义了一个方法(名为to)。
拥有该对象后,可以使用常用的点表示法调用该方法,从而生成上述情况中使用的chaining。或者重复使用 Blender的示例:

Convert(10, 'meters').to('feet') === 32.81`