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

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

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

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


当前回答

JavaScript中的闭包(类似于c# v2.0+中的匿名方法)呢?你可以创建一个函数来创建一个函数或“表达式”。

闭包的例子:

//Takes a function that filters numbers and calls the function on 
//it to build up a list of numbers that satisfy the function.
function filter(filterFunction, numbers)
{
  var filteredNumbers = [];

  for (var index = 0; index < numbers.length; index++)
  {
    if (filterFunction(numbers[index]) == true)
    {
      filteredNumbers.push(numbers[index]);
    }
  }
  return filteredNumbers;
}

//Creates a function (closure) that will remember the value "lowerBound" 
//that gets passed in and keep a copy of it.
function buildGreaterThanFunction(lowerBound)
{
  return function (numberToCheck) {
    return (numberToCheck > lowerBound) ? true : false;
  };
}

var numbers = [1, 15, 20, 4, 11, 9, 77, 102, 6];

var greaterThan7 = buildGreaterThanFunction(7);
var greaterThan15 = buildGreaterThanFunction(15);

numbers = filter(greaterThan7, numbers);
alert('Greater Than 7: ' + numbers);

numbers = filter(greaterThan15, numbers);
alert('Greater Than 15: ' + numbers);

其他回答

您还可以使用前面提到的原型链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文章中修改的代码。

如果你喜欢类似CLOS的基于类的OO, Joose是一个不错的对象系统。

// Create a class called Point
Class("Point", {
    has: {
        x: {
            is:   "rw",
            init: 0
        },
        y: {
            is:   "rw",
            init: 0
        }
    },
    methods: {
        clear: function () {
            this.setX(0);
            this.setY(0);
        }
    }
})

// Use the class
var point = new Point();
point.setX(10)
point.setY(20);
point.clear();

要将浮点数转换为整数,您可以使用以下神秘的技巧之一(请不要这样做):

3.14 >> 0(通过2.9999999999999999 >> .5?) 3.14 | 0(通过JavaScript中将浮点数转换为整数的最佳方法是什么?) 3.14 & -1 3.14 ^ 0 ~ ~ 3.14

基本上,对浮点数应用任何二进制操作都不会改变最终值(即恒等函数),最终会将浮点数转换为整数。

我知道我迟到了,但我只是无法相信+运算符的有用性除了“将任何东西转换为数字”之外没有被提及。也许这就是隐藏得有多好?

// Quick hex to dec conversion:
+"0xFF";              // -> 255

// Get a timestamp for now, the equivalent of `new Date().getTime()`:
+new Date();

// Safer parsing than parseFloat()/parseInt()
parseInt("1,000");    // -> 1, not 1000
+"1,000";             // -> NaN, much better for testing user input
parseInt("010");      // -> 8, because of the octal literal prefix
+"010";               // -> 10, `Number()` doesn't parse octal literals 

// A use case for this would be rare, but still useful in cases
// for shortening something like if (someVar === null) someVar = 0;
+null;                // -> 0;

// Boolean to integer
+true;                // -> 1;
+false;               // -> 0;

// Other useful tidbits:
+"1e10";              // -> 10000000000
+"1e-4";              // -> 0.0001
+"-12";               // -> -12

当然,你也可以用Number()来代替,但是+运算符要漂亮得多!

您还可以通过重写原型的valueOf()方法为对象定义一个数值返回值。在该对象上执行的任何数字转换都不会导致NaN,而是valueOf()方法的返回值:

var rnd = {
    "valueOf": function () { return Math.floor(Math.random()*1000); }
};
+rnd;               // -> 442;
+rnd;               // -> 727;
+rnd;               // -> 718;

这并不总是一个好主意,但您可以用简洁的表达式转换大多数内容。这里重要的一点是,JavaScript中并不是每个值都是对象,所以这些表达式会成功,而对非对象(如null和undefined)的成员访问将失败。特别要注意typeof null == "object",但你不能null. tostring(),或("name" in null)。

将任何东西转换为数字:

+anything
Number(anything)

将任何东西转换为无符号四字节整数:

anything >>> 0

将任何东西转换为字符串:

'' + anything
String(anything)

将任何东西转换为布尔值:

!!anything
Boolean(anything)

同样,使用不带“new”的类型名对于String、Number和Boolean的行为不同,返回一个基本数字、字符串或布尔值,但使用“new”将返回“盒装”的对象类型,这几乎是无用的。