你认为每个程序员都应该知道JavaScript的哪些“隐藏特性”?

在看到以下问题的优质答案后,我认为是时候向JavaScript请求它了。

HTML的隐藏特性 CSS的隐藏特性 PHP的隐藏特性 ASP的隐藏特性。网 c#的隐藏特性 Java的隐藏特性 Python的隐藏特性

尽管JavaScript可以说是目前最重要的客户端语言(问问谷歌就知道了),但令人惊讶的是,大多数web开发人员很少意识到它的强大。


当前回答

语法糖:内联for循环闭包

var i;

for (i = 0; i < 10; i++) (function ()
{
    // do something with i
}());

几乎打破了Douglas Crockford的所有代码惯例,但我认为它看起来很漂亮,从未减少:)


选择:

var i;

for (i = 0; i < 10; i++) (function (j)
{
    // do something with j
}(i));

其他回答

可以使用[]而不是。

这允许您查找与变量匹配的属性。

obj = {a:"test"};
var propname = "a";
var b = obj[propname];  // "test"

您还可以使用此命令获取/设置名称不是合法标识符的对象属性。

obj["class"] = "test";  // class is a reserved word; obj.class would be illegal.
obj["two words"] = "test2"; // using dot operator not possible with the space.

有些人不知道这一点,最终像这样使用eval(),这是一个非常糟糕的主意:

var propname = "a";
var a = eval("obj." + propname);

这更难阅读,更难发现错误(不能使用jslint),执行速度更慢,并可能导致XSS漏洞。

这里有一个简单的思考“this”的方法。函数中的'This'将引用该函数的未来对象实例,通常使用operator new创建。所以很明显,内部函数的“this”永远不会指向外部函数的实例。

以上建议可以让你远离麻烦。但是你可以用“this”做更复杂的事情。


示例1:


     function DriveIn()
     {
          this.car = 'Honda';
          alert(this.food);  //'food' is the attribute of a future object 
                             //and DriveIn does not define it.
     }

     var A = {food:'chili', q:DriveIn};  //create object A whose q attribute 
                                         //is the function DriveIn;

     alert(A.car); //displays 'undefined' 
     A.q();        //displays 'chili' but also defines this.car.
     alert(A.car); //displays 'Honda' 


规则如下:

当一个函数作为一个对象的属性被调用时,在函数内部(但在任何内部函数之外)出现的任何'this'都指向该对象。

我们需要明确,即使使用operator new,“The Rule of This”也适用。在幕后,new通过对象的构造函数属性将“this”附加到对象上。


示例2:


      function Insect ()
      {
           this.bug = "bee";
           this.bugFood = function()
           {
               alert("nectar");
           }
       }

      var B = new Insect();
      alert(B.constructor); //displays "Insect"; By "The Rule of This" any
                            //ocurrence of 'this' inside Insect now refers 
                            //to B.    

为了更清楚地说明这一点,我们可以不使用operator new创建一个Insect实例。

示例3:

   
    var C = {constructor:Insect};  //Assign the constructor attribute of C, 
                                   //the value Insect.
    C.constructor();               //Call Insect through the attribute. 
                                   //C is now an Insect instance as though it 
                                   //were created with operator new. [*]
    alert(C.bug);                  //Displays "bee." 
    C.bugFood();                   //Displays "nectar." 

[*]我能辨别的唯一实际区别是,在示例3中,'constructor'是一个可枚举属性。当使用operator new时,'constructor'变成一个属性,但不是可枚举的。如果for-in操作"for(var name in object)"返回该属性的名称,则该属性是可枚举的。

JavaScript没有块作用域(但它有闭包,所以让我们称它为偶数?)

var x = 1;
{
   var x = 2;
}
alert(x); // outputs 2

==运算符有一个非常特殊的属性,它创建了这个令人不安的等式(是的,我知道在其他动态语言中,如Perl,这种行为是预期的,但JavaScript通常不会尝试在比较中聪明):

>>> 1 == true
true
>>> 0 == false
true
>>> 2 == true
false

如果你用逗号分隔语句,你几乎可以在括号之间做任何事情:

var z = ( x = "can you do crazy things with parenthesis", ( y = x.split(" "), [ y[1], y[0] ].concat( y.slice(2) ) ).join(" ") )

alert(x + "\n" + y + "\n" + z)

输出:

can you do crazy things with parenthesis
can,you,do,crazy,things,with,parenthesis
you can do crazy things with parenthesis