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

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

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

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


当前回答

window.name的值在页面更改时保持不变,如果在同一个域中(如果在iframe中,使用document),可以被父窗口读取。getElementById(“你的帧的ID”). contentwindow .name来访问它),并且只受可用内存的限制。

其他回答

这个是超级隐藏的,只是偶尔有用;-)

可以使用原型链创建委托给另一个对象的对象,而无需更改原始对象。

var o1 = { foo: 1, bar: 'abc' };
function f() {}
f.prototype = o1;
o2 = new f();
assert( o2.foo === 1 );
assert( o2.bar === 'abc' );
o2.foo = 2;
o2.baz = true;
assert( o2.foo === 2 );
// o1 is unchanged by assignment to o2
assert( o1.foo === 1 );
assert( o2.baz );

这只包括o1上的“简单”值。如果你修改了一个数组或另一个对象,那么原型就不再“保护”原始对象。当你在Class定义/原型中有{}或[]时要小心。

这里有一个简单的思考“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)"返回该属性的名称,则该属性是可枚举的。

这是jQuery的一个隐藏特性,而不是Javascript,但因为永远不会有“jQuery的隐藏特性”的问题……

你可以在jQuery中定义自己的:something选择器:

$.extend($.expr[':'], {
  foo: function(node, index, args, stack) {
    // decide if selectors matches node, return true or false
  }
});

对于使用:foo的选择,例如$('div.block:foo("bar,baz") span'),函数foo将被用于匹配选择器中已经处理的部分的所有节点。论证的意义:

node holds the current node index is the index of the node in the node set args is an array that is useful if the selector has an argument or multiple names: args[0] is the whole selector text (e.g. :foo("bar, baz")) args[1] is the selector name (e.g. foo) args[2] is the quote character used to wrap the argument (e.g. " for :foo("bar, baz")) or an empty string if there is no quoting (:foo(bar, baz)) or undefined if there is no argument args[3] is the argument, including any quotes, (e.g. "bar, baz") or undefined if there are no arguments stack is the node set (an array holding all nodes which are matched at that point)

如果选择器匹配,函数将返回true,否则返回false。

例如,下面的代码将支持基于全文regexp搜索选择节点:

$.extend($.expr[':'], {
  matches: function(node, index, args, stack) {
    if (!args.re) { // args is a good place for caching
      var re = args[3];
      if (args[2]) { // get rid of quotes
        re = re.slice(1,-1);
      }
      var separator = re[0];
      var pos = re.lastIndexOf(separator);
      var modifiers = re.substr(pos+1);
      var code = re.substr(1, pos-1);
      args.re = new RegExp(code, modifiers);
    }
    return $(node).text().match(args.re);
  }
});

// find the answers on this page which contain /**/-style comments
$('.answer .post-text code:matches(!/\\*[\\s\\S]*\\*/!)');

使用.filter()的回调版本也可以达到类似的效果,但自定义选择器要灵活得多,通常可读性也更好。

令人惊讶的是,很多人都没有意识到它也是面向对象的。

下面是一些有趣的事情:

Comparing NaN with anything (even NaN) is always false, that includes ==, < and >. NaN Stands for Not a Number but if you ask for the type it actually returns a number. Array.sort can take a comparator function and is called by a quicksort-like driver (depends on implementation). Regular expression "constants" can maintain state, like the last thing they matched. Some versions of JavaScript allow you to access $0, $1, $2 members on a regex. null is unlike anything else. It is neither an object, a boolean, a number, a string, nor undefined. It's a bit like an "alternate" undefined. (Note: typeof null == "object") In the outermost context, this yields the otherwise unnameable [Global] object. Declaring a variable with var, instead of just relying on automatic declaration of the variable gives the runtime a real chance of optimizing access to that variable The with construct will destroy such optimzations Variable names can contain Unicode characters. JavaScript regular expressions are not actually regular. They are based on Perl's regexs, and it is possible to construct expressions with lookaheads that take a very, very long time to evaluate. Blocks can be labeled and used as the targets of break. Loops can be labeled and used as the target of continue. Arrays are not sparse. Setting the 1000th element of an otherwise empty array should fill it with undefined. (depends on implementation) if (new Boolean(false)) {...} will execute the {...} block Javascript's regular expression engine's are implementation specific: e.g. it is possible to write "non-portable" regular expressions.

[更新了一点,以回应良好的评论;请参阅评论]