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

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

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

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


当前回答

您还可以使用前面提到的原型链spoon16扩展(继承)类和重写属性/方法。

在下面的例子中,我们创建了一个类Pet并定义了一些属性。我们还重写了继承自Object的. tostring()方法。

在此之后,我们创建了一个Dog类,它扩展了Pet并重写了. tostring()方法,再次改变了它的行为(多态性)。此外,我们还向子类添加了一些其他属性。

在此之后,我们检查继承链以显示Dog仍然是Dog类型、Pet类型和Object类型。

// Defines a Pet class constructor 
function Pet(name) 
{
    this.getName = function() { return name; };
    this.setName = function(newName) { name = newName; };
}

// Adds the Pet.toString() function for all Pet objects
Pet.prototype.toString = function() 
{
    return 'This pets name is: ' + this.getName();
};
// end of class Pet

// Define Dog class constructor (Dog : Pet) 
function Dog(name, breed) 
{
    // think Dog : base(name) 
    Pet.call(this, name);
    this.getBreed = function() { return breed; };
}

// this makes Dog.prototype inherit from Pet.prototype
Dog.prototype = new Pet();

// Currently Pet.prototype.constructor
// points to Pet. We want our Dog instances'
// constructor to point to Dog.
Dog.prototype.constructor = Dog;

// Now we override Pet.prototype.toString
Dog.prototype.toString = function() 
{
    return 'This dogs name is: ' + this.getName() + 
        ', and its breed is: ' + this.getBreed();
};
// end of class Dog

var parrotty = new Pet('Parrotty the Parrot');
var dog = new Dog('Buddy', 'Great Dane');
// test the new toString()
alert(parrotty);
alert(dog);

// Testing instanceof (similar to the `is` operator)
alert('Is dog instance of Dog? ' + (dog instanceof Dog)); //true
alert('Is dog instance of Pet? ' + (dog instanceof Pet)); //true
alert('Is dog instance of Object? ' + (dog instanceof Object)); //true

这个问题的两个答案都是从Ray Djajadinata的一篇很棒的MSDN文章中修改的代码。

其他回答

当你写回调时,你有很多代码,看起来像这样:

callback: function(){
  stuff(arg1,arg2);
}

您可以使用下面的函数使它更简洁。

callback: _(stuff, arg1, arg2) 

它使用javascript的function对象中一个不太为人所知的函数apply。

它还显示了另一个可以用作函数名的字符:_。

function _(){
        var func;
        var args = new Array();
        for(var i = 0; i < arguments.length; i++){
                if( i == 0){
                        func = arguments[i];
                } else {
                        args.push(arguments[i]);
                }
        }
        return function(){
                return func.apply(func, args);
        }
}

正如Marius已经指出的,可以在函数中使用公共静态变量。

我通常使用它们来创建只执行一次的函数,或者缓存一些复杂的计算结果。

下面是我以前的“单例”方法的例子:

var singleton = function(){ 

  if (typeof arguments.callee.__instance__ == 'undefined') { 

    arguments.callee.__instance__ = new function(){

      //this creates a random private variable.
      //this could be a complicated calculation or DOM traversing that takes long
      //or anything that needs to be "cached"
      var rnd = Math.random();

      //just a "public" function showing the private variable value
      this.smth = function(){ alert('it is an object with a rand num=' + rnd); };

   };

  }

  return arguments.callee.__instance__;

};


var a = new singleton;
var b = new singleton;

a.smth(); 
b.smth();

如您所见,在这两种情况下构造函数都只运行一次。

For example, I used this approach back in 2004 when I had to create a modal dialog box with a gray background that covered the whole page (something like Lightbox). Internet Explorer 5.5 and 6 have the highest stacking context for <select> or <iframe> elements due to their "windowed" nature; so if the page contained select elements, the only way to cover them was to create an iframe and position it "on top" of the page. So the whole script was quite complex and a little bit slow (it used filter: expressions to set opacity for the covering iframe). The "shim" script had only one ".show()" method, which created the shim only once and cached it in the static variable :)

有些人会说这是品味问题,但是:

aWizz = wizz || "default";
// same as: if (wizz) { aWizz = wizz; } else { aWizz = "default"; }

三元操作符可以被链接到Scheme的(cond…):

(cond (predicate  (action  ...))
      (predicate2 (action2 ...))
      (#t         default ))

可以写成……

predicate  ? action( ... ) :
predicate2 ? action2( ... ) :
             default;

这是非常“实用的”,因为它可以在没有副作用的情况下对代码进行分支。所以不要:

if (predicate) {
  foo = "one";
} else if (predicate2) {
  foo = "two";
} else {
  foo = "default";
}

你可以这样写:

foo = predicate  ? "one" :
      predicate2 ? "two" :
                   "default";

也适用于递归:)

函数在JavaScript中是第一类公民:

var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };

var sum = function(x,y,z) {
  return x+y+z;
};

alert( passFunAndApply(sum,3,4,5) ); // 12

函数式编程技术可以用来编写优雅的javascript。

特别是,函数可以作为参数传递,例如Array.filter()接受回调:

[1, 2, -1].filter(function(element, index, array) { return element > 0 });
// -> [1,2]

你也可以声明一个“private”函数,它只存在于特定函数的作用域中:

function PrintName() {
    var privateFunction = function() { return "Steve"; };
    return privateFunction();
}

当使用console.log()用于Firebug时,防止在Internet Explorer中测试时出现恼人的错误:

function log(message) {
    (console || { log: function(s) { alert(s); }).log(message);
}