原文:http://arstechnica.com/journals/linux.ars/2007/08/27/javascript-for-all-ages?foo
1、objects and associative arrays
javascript中,对象属性操作与数组很类似。
但 javascript也为我们做了一些工作,把 数字转化为字符串。不过还是建议自己写清楚
foo[1] == foo[(1).toString()] == foo['1'];
2、cute type conversions
这些基本我们都知道。
也可看看
http://www.jibbering.com/faq/faq_notes/type_convert.html
0 + '' == 0
'' + 0 == 0
1 + '' == 1
'' + 1 == 1
0 + 'a' == '0a'
'a' + 0 == 'a0'
但这个技巧呢?很多lib里面都用了。
var a=function(){}
var b=new a();
alert(!b)
alert(b)
3、iteration
prototype.js,jQuery。n多的FP的东西。
4、anonymous functions
也见 http://developer.mozilla.org/en/docs/New_in_JavaScript_1.6
yield,反正我自己用起来很别扭。
喜欢ruby的yield.
var range = function (start, stop, step) {
return function () {
var at = start;
start += step;
if (at < stop) return at;
else throw new Error();
};
};
var next = range(0, 6, 2);
alert(next())//0
alert(next())//2
alert(next())//4
大量的应用”闭包“,始终感觉性能上有些问题。可能是个人感觉
5、enclosure
(function () {
...
}).call(this);
语言的”最小单元“,不知道该叫什么。但是java里面,所谓”最小单元“,也是一个类。而javascript或ruby之类的,一断代码就可以,可以通过上面的方法动态注入执行环境。我不是很喜欢javascript的eval的功能。
with也有类似功效。好象很多书都不建议用with。性能慢是一个原因。感觉javascript语言不想让代码编写者了解“scope chain”。所以闭包,with,eval等等都不是很流行。可能这方面javascript设计的不是很严谨???
6、context object manipulation
Function.apply
Function.call
在这里很关键,
在java中,那么多设计模式都是关于接口的,我理解为java中接口是最小单元,如果没有接口,你根本不知道那些方法的context object是什么,也不可能执行方法。
而javascript呢?有function就好了,注意this都ok了。
读了jQuery代码后,在这方面有很多感想,有时间具体分析一下。
7、variadic arguments
小tip。
8、binding
与第六差不多。
跑题:
javascript模拟java的面向对象编程时,其实也模拟的java的”缺点“,状态保存的位置!!!
var Button=function (dom){
this.**=**;
this.**=**;
}
这种”类“其实完全没有必要的!!!
9、lazy function definition
大家讨论不少了!
相同的功能,其实YUI代码里早用到了。
http://developer.yahoo.com/yui/docs/Dom.js.html
见getStyle setStyle 等。
var getPi = function () {
var pi = calculatePi();
getPi = function () {
return pi;
}
return pi;
};
我到是不认为它这例子好。真正这些功能都在lib中实现,象cache,function覆盖等!
10、polymorphic callable objects
新的想法,区别java之类的多态
var callableType = function (constructor) {
return function () {
var callableInstance = function () {
return callableInstance.callOverload.apply(callableInstance, arguments);
};
constructor.apply(callableInstance, arguments);
return callableInstance;
};
};
var SubmarineFactory = type(function () {
var length;
this.init = function (length) {
length = lengthValue;
};
this.callOverload = function () {
return Submarine(length);
};
});