你认为每个程序员都应该知道JavaScript的哪些“隐藏特性”?
在看到以下问题的优质答案后,我认为是时候向JavaScript请求它了。
HTML的隐藏特性 CSS的隐藏特性 PHP的隐藏特性 ASP的隐藏特性。网 c#的隐藏特性 Java的隐藏特性 Python的隐藏特性
尽管JavaScript可以说是目前最重要的客户端语言(问问谷歌就知道了),但令人惊讶的是,大多数web开发人员很少意识到它的强大。
你认为每个程序员都应该知道JavaScript的哪些“隐藏特性”?
在看到以下问题的优质答案后,我认为是时候向JavaScript请求它了。
HTML的隐藏特性 CSS的隐藏特性 PHP的隐藏特性 ASP的隐藏特性。网 c#的隐藏特性 Java的隐藏特性 Python的隐藏特性
尽管JavaScript可以说是目前最重要的客户端语言(问问谷歌就知道了),但令人惊讶的是,大多数web开发人员很少意识到它的强大。
当前回答
除了公共成员外,还可以使用闭包创建具有私有(在“类”定义之外不可访问)静态成员和非静态成员的“类”。
注意,下面的代码中有两种类型的公共成员。特定于实例的(在构造函数中定义),可以访问私有实例成员,共享成员(在原型对象中定义)只能访问私有静态成员。
var MyClass = (function () {
// private static
var nextId = 1;
// constructor
var cls = function () {
// private
var id = nextId++;
var name = 'Unknown';
// public (this instance only)
this.get_id = function () { return id; };
this.get_name = function () { return name; };
this.set_name = function (value) {
if (typeof value != 'string')
throw 'Name must be a string';
if (value.length < 2 || value.length > 20)
throw 'Name must be 2-20 characters long.';
name = value;
};
};
// public static
cls.get_nextId = function () {
return nextId;
};
// public (shared across instances)
cls.prototype = {
announce: function () {
alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
}
};
return cls;
})();
测试这段代码:
var mc1 = new MyClass();
mc1.set_name('Bob');
var mc2 = new MyClass();
mc2.set_name('Anne');
mc1.announce();
mc2.announce();
如果您有Firebug,您会发现除了在定义私有成员的闭包中设置断点之外,没有其他方法可以访问私有成员。
当定义需要严格验证值和完全控制状态更改的类时,这种模式非常有用。
要扩展这个类,你可以把MyClass.call(this);在扩展类的构造函数的顶部。您还需要复制MyClass。prototype对象(不要重用它,因为你也会改变MyClass的成员。
如果要替换announce方法,则需要调用MyClass。MyClass.prototype.announce.call(this);
其他回答
可以使用[]而不是。
这允许您查找与变量匹配的属性。
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漏洞。
函数在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();
}
嗯,这不是一个很重要的功能,但它非常有用:
显示可选择和格式化的警报:
alert(prompt('',something.innerHTML ));
真实和虚假价值的概念。你不需要做这种事
if(someVar === undefined || someVar === zero) ...
只是做的事:
if (! someVar)。
每个值都有一个对应的布尔表示。
有些人会说这是品味问题,但是:
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";
也适用于递归:)