dinghao

记录成长点滴

 

Ajax.net-Javascript

上个月开始看Ajax ToolKit代码,到Animations.js时发现,根据从Js高级程序设计学到的Js语法没有办法解释Animations的实现,细看MicrosoftAJax.js也是不懂地方很多。经过近一个月的Js学习,把一些体会记录下来,使其他人可以尽快的从OO观念转到Js。

 

态度

       以前以为Js是很弱的语言,这次深入的学习发现Js的功能出乎意料的强大。

工具

       Vs 带的编辑器:不专业,用它写代码验证自己的一些想法会被气死,太慢。Orcas据说增加了智能感知,从MicrosoftAjax.js的语法也可以看出对Linq的支持,支持智能感知也顺理成章,只是不知道对自己定义的函数有没有此功能。

       1st Javascript Editor:我试用发现不支持Json,某些语句和IE执行结果不同,对Closure的支持也有问题。

       Antechinus JavaScript Editor:支持Jaon,智能感知,9.0还增加了调试器,感觉不错。

       Google.com(百度越来越烂)

资料

       推荐唯一一本书, Js The Definitive Guid 5th edtion

买了本Js高级程序设计,读完后看Ajax源码才知道,这本书写的太不严密,许多地方让人误解(根本就是错误),因为根据此书的解释,根本就看不懂源码。

Ecma-262,写的也很晦涩,但是可以看看他的定义如:objects,Object,Function等。以免看到书中的对象函数都用OO的概念去理解。还可以看看那些概念是Behave,以免被不同的实现困扰。

注:我至少看到三篇blog说,Js的书唯一能看的就是 Definitive Guid,看其它的书基本都会让初学者走人歧途(我就是Js高级程序设计的受害者),部分原因是Ecma太过粗糙,不能给作者以指导。

OOJavascript

       不能陷入用OO理解Js的陷阱,分析JS设计时例外。

Object&Function

       Js内置的对象是Function或者是constructor FunctionFunction反过来又继承自Object。这就形成了很怪的一种关系,这是MicrosoftAjax.js中扩展FunctionType的基础。

       Array-Like,被用来形容对象。对象被定义为命名的值的集合,这些值可以引用另外的对象,可以用哈西表实现(ecma没有规定实现方式)。可以通过类似数组的语法引用对象的值:如object[‘s’][‘s’][‘s’],可以连续引用,MA.jsregisterNamespace的实现应用了这个特性。

       Function定义了prototypeObject定义了constructor。要区分用Function时使用的是Function作为Object的特性还是作为Function的特性。如把函数付给一个变量时,Functon是作为Object存在。i

       正因为Function也是ObjectFunction才能模拟出类似OO中的classinterface,inheritence等。

Function远比OO中的类灵活,再加上scop chain,闭包特性。从语言特性说Js比基于OO语言灵活的多。可以想象一下,一种东西可以如指针来回游走,又如可以动态增加功能的类。这就是Function,如果加上闭包,还可以切换scop

Reference Type

对象是引用类型,引用类型对象参数也是引用传递。

Scop

文本范围,定义函数时范围就被定义,可以说是静态的。但是callecma Activition Object是动态的,这就是闭包的基础,理解了这点js中最难的闭包和Scop chain就都简单了。

chain

我发现有三种chain,也许有别的链还没有发现,每种链对理解Js都很关键。

scop chain

最难的一种,又涉及到闭包。

在函数创建时,scop就被定死在他的文本范围,但是在调用函数时会创建call Objectcall Object作为scop的头,call Ojcet包含当前的参数,当前scop中的变量,最后引用到globle scop。每次搜索变量时,都是从当前call objectscop中查找,找到就不在向更下层的链遍历。有了callObject,只要保持内部Function的引用,就拥有了整条scop chain,闭包才能够实现。

prototype chain

       有了这条链,通过prototype实现继承成为可能。用不好也会导致些问题,如暴露obj.constructor.protype,function.prototype.constrctor。如高级编程好像例子就有这种问题。可以看看MA.jsregisterclass是怎么通过绕过这个问题的(MA.js把这个问题绕了过去,不同于Definitive Guid)。

constructor chain

       这样继承才能有多个层次。

Static

只是看起来像OO中的static,可以通过扩展Object的Method(不是prototype)实现。如:Type.RegisterNamespace

Private

如果在function中没有用var属于globle Object

http://www.crockford.com/javascript/private.html

Globle Object

       每种环境的Globle Object都可能不同,如Ie是window,Antechinus的Globle Object不知道是哪个对象,但是这造成不能在antechinus中运行MA,因为MA的Globle已经定死在window上了。

Literal&Json

Js支持对象和数字的Literal格式定义如:

Arrayvar b = [[1,{x:1, y:2}], [2, {x:3, y:4}]];

对象:var circle = { x:point.x, y:point.y+1, radius:2 };

上面的定义也是基于Json的。

Inheritance

除了类似OO的继承,对象和函数的Prototype间也称为继承,因为初始化构造函数时Prototype中的值好像是被继承下来的,并且是被其他实例共享,修改会影响到其他对象,这也产生了后面的Write&Read

Read&Write

访问变量时先查找构造函数中的变量,然后才搜索prototypePrototype第一个值指向了constructor,实现继承时必须注意。

但是写入是时不能修改对象的prototype,否则会影响整个继承链。因此通常在prototype中放入method和只读变量。

没有声明的变量不能读,但可以赋值,这时Js会自动声明。

Call &Apply

function.call(thisobj, args...)

thisobj

The object on which function is to be invoked. In the body of the function, thisobj becomes the value of the this keyword. If this argument is null, the global object is used.

Call&ApplyFunction最神奇的方法,他可以调用其他上下文的方法做为自己上下文的方法,因为如此继承用Apply实现才会少些很多代码。结合闭包实现了MA.js中的createDelegate,createCallback。上面是Definitive Guid中的定义。

Variables&Propertys

属性和变量相同,全局变量是globle对象的属性,局部变量是call对象的属性。

      Namespace

       本质是文本范围的实现,见Scope。不过MA.js的实现很强大。

上面粗略的分析了Js,一时就想起这么多,比较基本的如prototype没有提及。

       下一篇分析MicrosoftAjax.jsregisterNamespace,registerClass

posted on 2007-07-17 17:35  思无邪  阅读(2687)  评论(16编辑  收藏  举报

导航