【问题标题】:Best javascript syntactic sugar最好的 javascript 语法糖
【发布时间】:2010-09-15 21:38:17
【问题描述】:

这里有一些宝石:

字面量:

var obj = {}; // Object literal, equivalent to var obj = new Object();
var arr = []; // Array literal, equivalent to var arr = new Array();
var regex = /something/; // Regular expression literal, equivalent to var regex = new RegExp('something');

默认值:

arg = arg || 'default'; // if arg evaluates to false, use 'default', which is the same as:
arg = !!arg ? arg : 'default';

我们当然知道匿名函数,但是能够将它们视为文字并在现场(作为闭包)执行它们很棒:

(function() { ... })(); // Creates an anonymous function and executes it

问题: javascript 中还有哪些出色的语法糖?

【问题讨论】:

  • 我不知道 ||默认值语法。漂亮而紧凑,虽然不是那么直观。 (也许我见过,但从未理解。)
  • 我很难掌握三元语法。在你写了几次之后,它看起来就像你的第二天性。至于你可能见过的地方,我认为 jquery.js 和prototype.js 都使用它。
  • 如何解释每个例子?
  • 我不知道“arg || 'default'”。我希望它返回一个布尔值,但它返回的第一个值(从左边)计算为真(类似于 python)!这比 "arg = arg ? arg : 'default'" 好多了!
  • Chris Noe 典当了这个话题!

标签: javascript language-features syntactic-sugar


【解决方案1】:

以毫秒为单位获取当前日期时间:

Date.now()

例如,为一段代码的执行计时:

var start = Date.now();
// some code
alert((Date.now() - start) + " ms elapsed");

【讨论】:

  • 事实上,这是最好的 javascript 语法糖。一个winnar si yuo。
  • OrbMan,这可能取决于上下文;如果将它作为参数传递,它可能会被强制转换为 Object 而不是 Number 或 String,在这种情况下 + 已经将它强制转换为 Number。事实上,+ 似乎是 parseInt(value, 10) 的简写。
  • 更正:它确实与 parseInt(value, 10) 有一些不同。例如,+[3] 和 parseInt([3], 10) 都等于数字 3,但是 +[3, 4] == NaN 和 parseInt([3, 4], 10) == 3。
  • 呃...所有这些 parseInt(value, 10) 实例都应该是 parseFloat(value)。还有 Chris Noe,很抱歉评论垃圾邮件;)
  • 我的好奇心促使我在 jsperf 中尝试它,似乎性能最好的是规范的 getTime() :)(参考。jsperf.com/millisecondsdate
【解决方案2】:

对象成员资格测试:

变种道具 = { a: 1, b: 2 }; ("a" in props) // true ("b" in props) // true ("c" in props) // false

【讨论】:

  • 那肯定比 props.a 更简洁 === undefined 谢谢。
  • 即使 props = { a: undefined } 也是如此。
  • 仅供参考 - 当您尝试在 XPCNativeWrapper 对象上使用“in”时,Firefox 会抛出 TypeError。从 Firefox 4 开始,很多对象都被包装了。所以回到 props.a === undefined 在这些情况下。
【解决方案3】:

在 Mozilla(据说是 IE7)中,您可以使用以下方法创建 XML 常量:

var xml = ;

您也可以替换变量:

var elem = "html"; var text = "一些文字"; var xml = {文本}{elem}>;

【讨论】:

  • 真的吗?有其他引擎支持吗?
  • 只是想知道:一旦你创建了那个“xml”变量,你可以用它做什么?现在只是在 firebug 中使用它,它看起来好像没有任何方法或属性,并且您无法将其添加到 DOM。
  • E4X 文字是由于跨站点脚本包含攻击而造成的安全灾难,实际上并没有比仅仅能够说“var xml= new XML('')” 国际海事组织。
  • @CharlieSomerville 这不是风险。 E4X 可能会将“安全”[X][HT]ML 文件转换为活动 JS。请阅读code.google.com/p/doctype/wiki/ArticleE4XSecurity 了解此问题的背景。
【解决方案4】:

使用匿名函数和闭包创建私有变量(信息隐藏)和相关的 get/set 方法:

var getter, setter;

(function()
{
   var _privateVar=123;
   getter = function() { return _privateVar; };
   setter = function(v) { _privateVar = v; };
})()

【讨论】:

  • 花了我一点时间,但我明白了。这很整洁。
  • 我不久前在查看 swfobject 源时发现了一种类似的技术。使用闭包来创建私有变量/方法是我可能永远不会想到的。这有点酷。
  • 有了新的JS版本,我们可以使用更简单的if(true) { let _privateVar=123; }
  • 请注意此处的“狗球”风格潜在问题。见:twitter.com/paul_irish/status/176187448420864000?lang=en
【解决方案5】:

能够通过原型继承扩展原生 JavaScript 类型。

String.prototype.isNullOrEmpty = function(input) {
    return input === null || input.length === 0;
}

【讨论】:

  • 避免对数组这样做:stackoverflow.com/questions/61088/…
  • 这是真的,但前提是你使用 for(a in b) 循环。通常我使用框架,我相信其他人都会这样做。因此,我通常使用 .each()
  • 如果容器中的 any 代码使用 for(a in b),则可能会出现问题。当该容器是浏览器时,您可能会破坏浏览器中的其他代码(例如,该框架)。我被那个人盯上了。
  • 是的。好点,克里斯。我仍然认为原型继承是 JavaScript 的最佳特性之一 :)
  • for(var i in obj) { if(!obj.hasOwnProperty(i)) { continue; } ... }
【解决方案6】:

使用===比较值类型:

变量 i = 0; 变量 s = "0"; if (i == s) // 真 if (i === s) // 假

【讨论】:

  • 它实际上被称为严格相等——基本上它避免了所有在执行 == 时必须发生的类型转换
  • 其他语言(PHP)也称其为“身份”检查,即:这两个值是否相同
  • @nickf,这有点用词不当。 $var1 = 'string'; $var2 = 'string'; $var1 === $var2; // true,即使 $var1$var2 不相同(引用内存中相同的存储值),只是相同的类型和相同的值。
  • @eyelidlessness,我不确定 javascript 是否可以这样工作......字符串 (通常) 按值存储和传递。然而,对象被存储为参考:var1 = {a : 'b'}; var2 = {a : 'b'}; var1 === var2 // false.
  • @nickf,我明白这一点。但是您可以删除 PHP 代码中的印记并在 JavaScript 中获得相同的结果。这些字符串不是相同的,但它们的值是。
【解决方案7】:

多行字符串:

var str = "这是\ 一个\ 细绳。”;

由于您不能在不将空格添加到字符串中的情况下缩进后续行,因此人们通常更喜欢使用加号运算符连接。但这确实提供了很好的here document 功能。

【讨论】:

  • 公平警告 -- 如果 \'s 后面有任何尾随空格,则会引发异常。
【解决方案8】:

调整数组长度

length 属性是一个只读。 您可以使用它来增加或减少数组的大小。

var myArray = [1,2,3];
myArray.length // 3 elements.
myArray.length = 2; //Deletes the last element.
myArray.length = 20 // Adds 18 elements to the array; the elements have the empty value. A sparse array.

【讨论】:

  • 先生,我相信这一定是关于 SO 的最重要的答案。不再为我pushing,呵呵。非常感谢。
  • 实际上,使用这种方式创建的元素实际上并不存在(它们也没有未定义的值,但访问它们会使您未定义)。你也不能用 for..in 遍历它们。
【解决方案9】:

通过在空数组上利用 join 方法将字符串(例如“-”)重复特定次数:

var s = new Array(repeat+1).join("-");

当重复 == 3 时,结果为“---”。

【讨论】:

    【解决方案10】:

    与默认运算符一样,|| 是守卫运算符,&&

    answer = obj && obj.property
    

    相对

    if (obj) {
        answer = obj.property;
    }
    else {
        answer = null;
    }
    

    【讨论】:

    • 不一定是null。只有obj === null 时才会出现这种情况。
    • 也可以和||结合使用以确保在 obj 根本不存在或对象存在但 key 属性不存在的情况下进行备份。总是这样定义答案: answer = (obj && obj.property) || '备份道具';
    【解决方案11】:
    var tags = {
        name: "Jack",
        location: "USA"
    };
    
    "Name: {name}<br>From {location}".replace(/\{(.*?)\}/gim, function(all, match){
        return tags[match];
    });
    

    字符串替换的回调很有用。

    【讨论】:

      【解决方案12】:

      Getters and setters:

      function Foo(bar)
      {
          this._bar = bar;
      }
      
      Foo.prototype =
      {
          get bar()
          {
              return this._bar;
          },
      
          set bar(bar)
          {
              this._bar = bar.toUpperCase();
          }
      };
      

      给我们:

      >>> var myFoo = new Foo("bar");
      >>> myFoo.bar
      "BAR"
      >>> myFoo.bar = "Baz";
      >>> myFoo.bar
      "BAZ"
      

      【讨论】:

      • 是的,它会比我现在使用的方法好一点。
      • @eyelidlessness 它在 IE 实现的 ECMAScript 5 的 Object.defineProperty 中,其他浏览器可以使用 defineGetter
      • IE8 只实现了 DOM 对象的 getter/setter,所以在让你自己的对象 API 更整洁时它是没有用的:-/
      【解决方案13】:

      这不是 javascript 独有的,但可以节省三行代码:

      check ? value1 : value2
      

      【讨论】:

      • 不赋值时是否有等价物(例如 fnName ? fnName : defaultFn;)?
      • 不,三元运算符严格用于表达式;没有声明
      • 您可以使用它来评估匿名函数,例如: "var myFunc = (browserIsIE ? function() { ... } : function() { ... })" 。就个人而言,我不会推荐它,因为它非常令人困惑,但至少它是可能的。
      • "evaluate" 在之前的评论中可能不是最好的词。嗯..分配?
      • @eyelidlessness:是:fnName ? fnName() : 默认Fn(); // 单独一行,有效
      【解决方案14】:

      更多关于 levik 的例子:

      var foo = (condition) ? value1 : value2;
      

      【讨论】:

      • 你不需要括号。三元运算符在许多其他语言中也很常见。
      • 当条件语句中存在语法歧义时,括号会有所帮助(例如,确定 ? 适用于条件语句的哪个部分)。
      【解决方案15】:

      Javascript 1.6 上的Array#forEach

      myArray.forEach(function(element) { alert(element); });
      

      【讨论】:

        【解决方案16】:

        跟随 obj || {default:true} 语法:

        用这个调用你的函数:hello(neededOne && neededTwo && needThree) 如果一个参数未定义或为假,那么它将调用 hello(false),有时有用

        【讨论】:

          【解决方案17】:

          在具有一组固定组件的解析情况下:

          var str = "John Doe";
          

          您可以使用“解构赋值”语法将结果直接赋值给变量:

          var [fname, lname] = str.split(" ");
          alert(lname + ", " + fname);
          

          这比以下更具可读性:

          var a = str.split(" ");
          alert(a[1] + ", " + a[0]);
          

          交替:

          var [str, fname, lname] = str.match(/(.*) (.*)/);
          

          请注意,这是Javascript 1.7 功能。所以目前是 Mozilla 2.0+ 和 Chrome 6+ 浏览器。

          【讨论】:

          • 我在 Safari Javascript 控制台中尝试了这个,结果导致解析错误。
          • Snap,我想我只在 Firefox 中使用过这个。我添加了浏览器兼容性说明。
          • 它在 Chrome 6 上不起作用。它提供SyntaxError: Unexpected token [
          • 一项小研究开始表明 chrome 的 1.7 并不完全是标准的。据报道 let 也有问题:stackoverflow.com/questions/300185/…
          • 它仍然无法在 Chrome 13 上运行。关于何时实施的任何线索?
          【解决方案18】:

          立即调用箭头函数:

          var test = "hello, world!";
          (() => test)(); //returns "hello, world!";
          

          【讨论】:

            【解决方案19】:

            我忘了:

            (function() { ... }).someMethod(); // Functions as objects
            

            【讨论】:

              【解决方案20】:

              简单地创建一个匿名对象字面量:({})

              例子:需要知道对象是否有valueOf方法:

              var hasValueOf = !!({}).valueOf

              额外的语法糖:双重不是'!!'非常简洁地将几乎所有内容转换为布尔值。

              【讨论】:

                【解决方案21】:

                我喜欢能够 eval() 一个 json 字符串并返回一个完全填充的数据结构。 我讨厌必须至少写两次(一次用于 IE,一次用于 Mozilla)。

                【讨论】:

                  【解决方案22】:

                  将常用的关键字(或任何方法)分配给像 ths 这样的简单变量

                    var $$ = document.getElementById;
                  
                    $$('samText');
                  

                  【讨论】:

                  • 这不起作用(至少在 Chrome 中),因为 this 值丢失了。相反,您应该使用document.getElementById.bind(document)。如果没有bind,它只是分配HTMLDocument.prototype.getElementById 函数,没有应该在document 上调用它的信息。
                  【解决方案23】:

                  JavaScript 的 Date 类提供了一个半“流利的接口”。这弥补了无法直接从 Date 类中提取日期部分:

                  var today = new Date((new Date()).setHours(0, 0, 0, 0));
                  

                  它不是一个完全流畅的接口,因为下面只会给我们一个数值,它实际上不是一个 Date 对象:

                  var today = new Date().setHours(0, 0, 0, 0);
                  

                  【讨论】:

                    【解决方案24】:

                    默认后备:

                    var foo = {}; // empty object literal
                    
                    alert(foo.bar) // will alert "undefined"
                    
                    alert(foo.bar || "bar"); // will alert the fallback ("bar")
                    

                    一个实际的例子:

                    // will result in a type error
                    if (foo.bar.length === 0)
                    
                    // with a default fallback you are always sure that the length
                    // property will be available.
                    if ((foo.bar || "").length === 0) 
                    

                    【讨论】:

                      【解决方案25】:

                      这是我刚刚发现的一个:调用函数前的空值检查:

                      a = b && b.length;
                      

                      这是一个较短的等价于:

                      a = b ? b.length : null;
                      

                      最好的部分是您可以检查属性链:

                      a = b && b.c && b.c.length;
                      

                      【讨论】:

                        【解决方案26】:

                        我喜欢使用列表的简单性:

                        var numberName = ["zero", "one", "two", "three", "four"][number];
                        

                        还有哈希:

                        var numberValue = {"zero":0, "one":1, "two":2, "three":3, "four":4}[numberName];
                        

                        在大多数其他语言中,这将是相当繁重的代码。默认值也很可爱。例如报错码:

                        var errorDesc = {301: "Moved Permanently",
                                         404: "Resource not found",
                                         503: "Server down"
                                        }[errorNo] || "An unknown error has occurred";
                        

                        【讨论】:

                        • 这看起来棒极了,它的技术名称是什么?
                        【解决方案27】:

                        int 到字符串转换

                        var i = 12;
                        var s = i+"";
                        

                        【讨论】:

                        • 在我看来,这并不比直接执行 i.toString() 或 String(i) 更“甜蜜”。短!= 糖。
                        【解决方案28】:
                        element.innerHTML = "";  // Replaces body of HTML element with an empty string.
                        

                        删除元素所有子节点的快捷方式。

                        【讨论】:

                        • 这不是真正的 Javascript,它是 DOM,而且目前还不是标准的。
                        【解决方案29】:

                        如果不可能,将字符串转换为默认为 0 的整数,

                        0 | "3" //result = 3
                        0 | "some string" -> //result = 0
                        0 | "0" -> 0 //result = 0
                        

                        在某些情况下可能很有用,主要是当 0 被认为是不好的结果时

                        【讨论】:

                          【解决方案30】:

                          Template literals

                          var a = 10;
                          var b = 20;
                          var text = `${a} + ${b} = ${a+b}`;
                          

                          那么 text 变量将如下所示!

                          10 + 20 = 30

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 2012-05-22
                            • 1970-01-01
                            • 1970-01-01
                            • 2020-12-14
                            • 1970-01-01
                            • 2015-11-16
                            • 2013-07-05
                            • 2011-04-21
                            相关资源
                            最近更新 更多