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

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

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

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


当前回答

如果你喜欢类似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();

其他回答

JavaScript使用Date()的方式让我很兴奋!

function isLeapYear(year) {
    return (new Date(year, 1, 29, 0, 0).getMonth() != 2);
}

这是真正的“隐藏特性”。

编辑:删除了评论中建议的“?”条件。 是:……new Date(year, 1,29,0,0).getMonth() != 2 ?真:假…… 详情请看评论。

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

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

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

可以使用[]而不是。

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

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漏洞。

与。

它很少被使用,坦率地说,很少有用……但是,在有限的情况下,它确实有它的用途。

例如:对象字面量对于快速在新对象上设置属性非常方便。但是,如果需要更改现有对象的一半属性,该怎么办呢?

var user = 
{
   fname: 'Rocket', 
   mname: 'Aloysus',
   lname: 'Squirrel', 
   city: 'Fresno', 
   state: 'California'
};

// ...

with (user)
{
   mname = 'J';
   city = 'Frostbite Falls';
   state = 'Minnesota';
}

Alan Storm指出,这可能有点危险:如果用作上下文的对象没有被赋值的属性之一,它将在外部作用域被解析,可能会创建或覆盖一个全局变量。如果你习惯了用默认值或空值未定义的对象编写代码,这是特别危险的:

var user = 
{
   fname: "John",
// mname definition skipped - no middle name
   lname: "Doe"
};

with (user)
{
   mname = "Q"; // creates / modifies global variable "mname"
}

因此,避免使用with语句进行这种赋值可能是一个好主意。

请参见:JavaScript的“with”语句是否有合法用途?