数组定义方式
var myArray = new Array(1,2,3,4,) //普通方式var myArray = new Array(20) //20个元素
var myArray = //数组直接量
javascript.png
javascript.pngJavaScript 1.6~1.8上的高级技巧
在jslibs的项目wiki上看到这些技巧,都是一些在mozilla spidermonkey javascript上的高级戏法。在JScript上不能用的哈~。这里转过来,很多技巧挺有趣的。原文引用在:
http://code.google.com/p/jslibs/wiki/JavascriptTips
------------------------------------------
1. destructuring assignments
JavaScript 1.7var{a:x}={a:7};
Print(x);// prints: 7
2. Generator ExpressionsJavaScript 1.7[ y for( y in[5,6,7,8,9])]// is
and[ y for each ( y in[5,6,7,8,9])]// is
Because in for extracts index names, and for each extracts the values.3. Advanced use of iteratorsJavaScript 1.8Number.prototype.__iterator__ =function(){
for( let i =0; i <this; i++)
yield i;
};
for( let i in5)
print(i);
prints:1
2
3
4
5
This make Number object to act as a generator.4. Expression ClosuresJavaScript 1.8function(x) x * x;
Note that braces {...} and return are implicit5. Basic debuggingJavaScript 1.6LoadModule('jsstd');
functionThrowAnError(){
(function(){
thrownewError("Whoops!");
})();
}
try{
ThrowAnError()
}catch(e){
Print(e.stack);
}
prints:Error("Whoops!")@:0
()@test.js:7
ThrowAnError()@test.js:5
@test.js:14
6. Multiple-value returnsJavaScript 1.7function f(){
return[1,2];
}
var[a, b]= f();
Print( a +' '+ b );// prints: 1 2
7. Operator [ ] and strings ( like charAt() )JavaScript 1.6var str ='foobar';
Print( str[4]);
prints:a
8. indexOf() and lastIndexOf() Works on ArrayJavaScript 1.6var obj ={};
var arr =['foo',567, obj,12.34];
Print( arr.indexOf(obj));// prints: 2
9. Using Array functions on a non-Array objectJavaScript 1.7var obj ={};
Array.push(obj,'foo');
Array.push(obj,123);
Array.push(obj,5.55);
Print( obj.toSource());// prints: ({0:"foo", length:3, 1:123, 2:5.55})
10. Simulate threads using yield operatorJavaScript 1.7var scheduler =newfunction(){
var _workers =[];
this.Add=function( worker ){
_workers.push(new worker());
}
this.Run=function(){
while( _workers.length )
for each (var worker in _workers )
try{
worker.next();
}catch(err if err instanceofStopIteration){
_workers.splice( _workers.indexOf(worker),1);
}
}
}
function worker1(){
for(var i =0; i <5; i++){
Print('worker1: '+i,'\n');
yield;
}
}
scheduler.Add(worker1);
function worker2(){
for(var i =0; i <10; i++){
Print('worker2: '+i,'\n');
yield;
}
}
scheduler.Add(worker2);
scheduler.Run();
prints:worker1:0
worker2:0
worker1:1
worker2:1
worker1:2
worker2:2
worker1:3
worker2:3
worker1:4
worker2:4
worker2:5
worker2:6
worker2:7
worker2:8
worker2:9
11. swap two variablesJavaScript 1.7var a =1;
var b =2;
[a,b]=[b,a];
12. Destructuring assignment with function argumentsJavaScript 1.7function foo([a,b]){
Print(a);
Print(b);
}
foo([12,34]);
Prints:12
34
13. JavaScript scope and LET instructionJavaScript 1.7var x =5;
var y =0;
let (x = x+10, y =12){
Print(x+y);
}
Print(x+y);
prints:27
5
or,for( let i=0; i <10; i++){
Print(i +' ');
}
Print(i);
prints:0123456789 test.js:4:ReferenceError: i isnotdefined
14. Iterate on valuesJavaScript 1.6for each (var i in[3,23,4])
Print(i)
Prints:3
23
4
chinastock_detail_getinfo
http://hq.sinajs.cn/format=js&list=sh600036,s_sh000001,s_sz399001,s_sz399106,s_sh000300var hq_str_sh600036="招商银行,13.45,13.16,13.16,13.47,13.12,13.15,13.16,36584713,487881240,8000,13.15,24701,13.14,23279,13.13,53300,13.12,104200,13.11,16249,13.16,9100,13.17,50600,13.18,20500,13.19,9900,13.20,2008-12-15,11:35:58";
var hq_str_s_sh000001="上证指数,1962.598,8.383,0.43,459682,3135490";
var hq_str_s_sz399001="深证成指,7101.808,9.101,0.13,3601965,376566";
var hq_str_s_sz399106="深证综指,588.127,3.386,0.58,4274294440,1486010";
var hq_str_s_sh000300="沪深300,1973.973,13.593,0.69,280981,2304260";
被调用:chinastock_detail_getshtml
setTimeout(chinastock_detail_getinfo,20);
gZealChinaStock.m_ajaxRequest.responseText.split("\n").join("").split("\r").join("").split(';');
stockpattern = new RegExp('var hq_str_'+curStock.m_sFixid+'="([^"]+)";','g');
调用:
chinastock_detail_setstockinfo
调用:
chinastock_detail_setbigstock
http://finance.sina.com.cn/realstock/company/sz399001/nc.shtml
[ 本帖最后由 faunus 于 2008-12-15 22:37 编辑 ] 对于gZealChinaStock对像的创建方式再作一点说明
引出一种类似与面向对象的设计模式
[*]Crab = function(){//类的定义形式!![*]
this.leg = 10;//成员变量!![*]
//成员变量都写在这里[*]};[*]
[*]Crab.prototype = {[*]
say : function(){alert('we hava '+this.leg+' legs');}[*]
//成员方法都写这里[*]};[*]
[*]var
crabObj = new
Crab();[*]
[*]crabObj.say();
如果你以前玩过C++,那么一定非常熟悉了。这种类的定义方式是Ext的基础所在。
var crabObj = new Crab();其实执行了2个步骤!
第一:执行this.leg = 10,其结果就是crabObj.leg = 10
第二:将Crab.prototype这个对象给了crabObj,好比crabObj.say = Crab.prototype.say;
说白了,第一步交接成员变量,第二步交接成员方法。
还有些朋友喜欢这样定义类
function Crab(){
this.leg = 10;
}
当然也是可以的
这就是最最普通的类的定义方式了。
======================
有了上面的基础,我们这一节来模拟一个简单的继承
[*]Crab = function(){[*]
this.leg = 10;[*]};[*]
[*]Crab.prototype.say = function(){alert('we hava '+this.leg+' legs')};[*]
[*]GenCrab = function(){//螃蟹进化成人,变成蟹将了,只有2条腿了[*]
this.leg = 2;[*]}[*]
[*]function
extend(child,father){//定义出一个继承函数,有2个参数,子类,父类[*]
child.prototype = father.prototype;[*]}[*]
[*]extend(GenCrab,Crab);//这样一来,蟹将也有say的方法了[*]
[*]gCrab = new
GenCrab();[*]
[*]gCrab.say();//执行出来 we hava 2 legs
怎么样,蟹将已经将螃蟹的方法继承下来了吧?那如果要将父类的属性也继承下来呢?我想到2个方法:
第一、把父类的属性写入prototype中,如Crab.prototype.leg = 10
第二、GenCrab.prototype = new Crab();不知道你能不能看懂,呵呵,估计网上都没有人这样用过,但这样子写能把属性和方法全部继承,其中的奥秘,请您自己思考下
好了,我们进入主题,怎么将属性继承下来的呢?
答案是第一种方法。如果您仔细看过我写的第一篇文章,您一定会说,规范约定,只有方法才写在prototype中的呀,怎么能把属性也写入呢?岂不是把清楚的事情又弄复杂了?
聪明的Ext团队,的的确确是用第一种方法的,只是在写法上稍稍改变了下
[*]function
extend(child,father,override){//定义出一个继承函数,有2个参数,子类,父类,重载对象[*]
child.prototype = father.prototype;[*]
[*]
for(var
m
in
override){//将重载对象里面所有的东西(这里说的东西,无非就是属性和方法)都拿出来赋给子类,作为子类的属性或者方法[*]
child.prototype[m] = override[m];[*]
}[*]}
这样一来,又有了新的规范了,把类的属性都往override里面写,把方法仍旧往prototype里面写,我下面举个例子
[*]function
extend(child,father,override){//定义出一个继承函数,有2个参数,子类,父类,重载对象[*]
child.prototype = father.prototype;[*]
[*]
for(var
m
in
override){//将重载对象里面所有的东西(这里说的东西,无非就是属性和方法)都拿出来赋给子类,作为子类的属性或者方法[*]
child.prototype[m] = override[m];[*]
}[*]}[*]
[*]Crab = function(){[*]
//这里不写属性了[*]};[*]
[*]extend(Crab,Object,{leg:10,eye:2});//让Crab继承绝对父类Object,并把属性写到这里来,因为螃蟹和蟹将都有2只眼睛,所以蟹将一会将继承这个属性[*]
[*]Crab.prototype.say = function(){alert('we hava '+this.leg+' legs, '+this.eye+' eyes')};//方法仍旧在这里定义[*]
[*]GenCrab = function(){[*]}[*]
[*]extend(GenCrab,Crab,{leg:2});//这里,眼睛和脚都从父类那里继承过来了,但蟹将只有2只脚,所以我们只需要覆盖脚这个属性就可以了[*]
[*]gCrab = new
GenCrab();[*]
[*]gCrab.say();// we have 2 legs, 2 eyes
好了,属性和方法都已经可以继承了
========================
源代码来分析
[*]extend : function(){[*]
// 内联函数,不懂?就是将这个方法编译后放入内存中[*]
var
io = function(o){[*]
for(var
m
in
o){[*]
this[m] = o[m];[*]
}[*]
};[*]
return
function(sb, sp, overrides){[*]
if(typeof
sp == 'object'){//如果子类还不存在,只有父类和一些属性,那么就调用这2个参数,来构造一个子类,这里面的第三步非常神奇,很难解释的清楚,大致意思就是构造出这么匿名类,并将父类的构造方法借给它用用,嘿嘿,这么解释还不明白就留言吧[*]
overrides = sp;[*]
sp = sb;[*]
sb = function(){sp.apply(this, arguments);};[*]
}[*]
var
F = function(){}, sbp, spp = sp.prototype;//sb代表子类,sbp代表子类prototype,sp代表父类,spp代表父类prototype[*]
F.prototype = spp;[*]
sbp = sb.prototype = new
F();//其实就是child.prototype = father.prototype,new F()看不懂看第二节[*]
sbp.constructor=sb;//这2步一会儿细说[*]
sb.superclass=spp;[*]
if(spp.constructor == Object.prototype.constructor){//这个分支也不可以不管[*]
spp.constructor=sp;[*]
}[*]
sb.override = function(o){//给子类赋予一个override方法[*]
Ext.override(sb, o);[*]
};[*]
sbp.override = io;//给子类的对象赋予override方法[*]
Ext.override(sb, overrides);//将overrides里面的东西,全部赋予子类的prototype里面,不懂看第二节[*]
return
sb;//将这个全新包装的子类返回[*]
};[*]
}(),
我们来详细说说 sbp.constructor=sb 这个东东,为什么要写这么一步呢?因为child.prototype =father.prototype这步执行好后,会把child的constructor给抹掉,所以要把它重新指回来,那么为什么一定要配上这个constructor呢?网上有很多解释,但大都是一抄例子了事,搞了半天还是不明白有什么用处,其实constructor只是类的一个引用,当我们把一个对象调用来调用去,我们都忘记这个对象是由谁创建的时候,它就派上用场了,obj.constructor返回的就是创建obj的那个类了,明白了吧?其次,constructor还有一个方法就是反向调用,比如这样写obj.constructor.call(this),意思是用obj去调用obj的构造方法。恩恩……非常难理解,我打算后面的章节好好介绍它的用途。
sb.superclass=spp呢?superclass又是什么?这个是Ext无中生有的一个属性而已,让子类知道它的父类是谁而已,一个标记,呵呵
综上,三部曲已经出来了吧?
第一、将属性和方法都继承下来
第二、恢复constructor,建立superclass指针
第三、将子类的属性写入到子类里
看完这3节,我想你对Ext.extend不仅有了了解,而且应该体会到Ext的编码规范,通常定义一个类,有这个三步
第一:定义Child类
Child = function(){
}
第二:Ext.extend(Child,Father,{定义Child的属性})
第三:Child.prototyp = {定义Child的方法};
或者可以只用父类和属性直接构造子类
Child = Ext.extend(Father,{});
Ext更多用这个方法,并且将方法也写入{}里面,这个方法较之上面的,多了一个神奇的第三步,见上面的代码,期间的奥秘就在于,new Child()的时候,委托谁来构造,上面是Child自己来构造,而下面这种调用方式是委托Father来构造
您照着这样的思路去看源代码定会轻松不少的:) 爪,以后学习下。。