对于要不要回这个贴,我还是挺纠结的。既然几位老版都来讲话,又有Hax在这里垫底,我还是来讲讲。但是,老实说,你们口水你们的口水,我是来讨论技术问题——打酱油、路过、真巧呵。这里是51js。原本一个广告贴,被搞到骂战实在无趣。回到技术上来,纯说说技术,css8也务一下实,不要拿“反正我还没有看出什么问题”这样的话来填数。
我只说技术。随便说,hax讲闭包那章写得有点乱,我认账。呵呵。
关于hax提到的一大堆问题,我来理一下:
这个作用域链(Box.prototype.constructor.constructor.prototype)很长,长得几乎能够让
人背过气,它 是什么玩意?
“作用域(链)”通常是一个运行期的概念。在静态讨论它时,通常是以代码块(代码上下文位置)来做参考的。而作者列出了一个长长的属性存取,又说它是“作用域(链)”,是概念上出了问题。作者举的这个例子,只能用于讨论原型继承方面的一些问题,与作用域无关。
从底层来看对象,对象就是一系列属性的集合,这与其他语言中的列表结构类似。
“对象=属性包”,这个简单而生动的定义是anders说过的,我也常常拿来讲给别人听。所以这里没错。但hax用红色标出了“列表”两个字,他的意思是存疑于:“对象”与“列表”有什么关系吗?这还真是个问题。
1、在Delphi里面,TList与TStringList是两件事。TList是指针列表,没有“名-值”概念,所以TList不适于跟“对象”来做比较,反倒是说“对象跟TStringList有些类似”是可以的。但是,作者在书里没有指出“其它语言”是哪一种,所以这里就不好讲了。
2、再说,以《数据结构》这样的教材为例,列表也是没有“名-值”概念的,所以不适宜与“对象”来比较。
3、其三,作者原意是“从底层来看对象”,那就整个儿不对了。底层来看对象,对象其实不是“列表”这种结构的。(在SpiderMonkey的实现中,)它是表没错,但是是链表。
例如,a 引用 o,但是如果 o 的值发生了变化,则 a 就不指向 o 了
1、一般来说,“a引用o”,在代码上的含义是:
a.x = o;
2、接下来,作者说,“如果 o 的值发生了变化”,那么代码上的含义是:
o = y;
或
o.mmm = nnn;
3、再接下来,作者说,“则 a 就不指向 o 了”。请问,作者的陈述正确吗?
(1)其实a从来就没有指向过o。因为a与o并不是同一个东西,如果a指向o,就是同一个东西的引用关系了。
(2)如果说a.x引用指向了o,那么上述的过程发生后,a.x的引用关系其实并没有发生变化。
综上:作者表达确有问题。
o = new Array(); // 覆盖对象o
这个其实没什么问题。只是我常用“重写”,以及“重写变量o”。因为这里与o是不是一个对象没关系。
各家浏览器的JavaScript 引擎也各不相同,分 歧最明显的就是 DOM实现部分。
老实说,你讨论JavaScript就成了,把DOM拉进来做什么?DOM、CSS与JS三者是同一层级上的东西,按你的说法,却是JS包括了DOM——那么ECMA Script也该对DOM做标准化了?
IE,没有什么好说的了,一个狂妄的巨人。它最先提供支持 W3C DOM 标准和XMLHttpRequest 组件,但却是最后一个完全支持客户端JavaScript 语言标准的浏览器。
这个,历史问题。翻书吧。css8与hax各拿证据便是。
个人品味。反正我也喜欢IE的用户体验。更何况css8还说是“之一”。
Safari 浏览器的渲染引擎为 KHTML,这个引擎对于JavaScript 的支持比较差,无法与Mozilla 的 Gecko引擎和微软的 Trident 引擎相抗衡。
好与差的评判是主观的,无聊的。但Hax在这里指出的,却是说“KHTML其实并不包括JavaScript 支持”。css8大概从来没有签出过safari/webkit的代码包。“览器的渲染引擎为 KHTML”正确,但人家的JS引擎是叫JavaScript Core。而后面说Gecko与Trident 引擎,也错了。Mozilla的js引擎叫SpiderMonkey,微软的叫JScript。你讨论渲染引擎就罢了,却把JS引擎与之混为一谈……
据说,Opera 浏览器对标准的支持度最高,在特殊用户群中具有很高的威望,但是它的瑕疵也非常明显。
这个,hax大概只是讲你的“据说”没有出处吧。老实说,opera对js标准的支持是很顽固的,例如标准不支持caller,opera就死活也不支持——我很郁闷。
WebCore 和 WebKit 引擎都是 KHTML 引擎的衍生产品。
无言。你查历史吧。
当然,也容易引发垃圾泛滥,甚至出现内存外溢的现象。
没去读原书这一段的上下文。但一般不会说“内存外溢”,而是“内存溢出”。如无必要,益尊重惯例吧。
l 计算需要对象,于是就产生了数据。
l 计算需要效率,于是就产生了类型。
l 计算需要控制,于是就产生了变量。
第一句,如果你不打算与“Object”混淆。建议改成“计算需要目标”。
第二句,类型,与效率有必然关系吗?
第三句,“计算的控制”,通常就成逻辑了。变量或变量名,其实最早的概念是叫“引用数”的。它不过是一个标识。所以,如果说“计算目标(或被计算对象)需要标识,所以产生了变量”,大概更好。
而类型正是数据的单位,通俗地说就是计算机指令一次可以操作的数据块大小。
例如,双字节一次可以操作 32 位数据,……
老实说,这段太大了。我没读完。但作者说“如果没有各种数据类型,则计算机只有一个单位(即字节)……”,这是不负责任的。因为“字节”也是数据类型。放弃所有数据类型,以“纯粹的计算机”来讨论,则唯一单位是“位(bit)”。至于,如果要讨论到计算机的原理,以某类确定的机型而言,可以以总线类型来作为基本类型——这包括了寄存器、总线在操作位数上的一致性。例如32位机器,则可以说“32位整型”或者“双字(DWORD)”为基本类型。
又,正好又看到上文中的一个小错误“双字节一次可以操作 32 位数据”,这里应该是“16位”才对哦。
面向对象是编程方法,而不是数据抽象。把前面的“面向”去了就对了。
弱类型……当然这也是以牺牲开发速
度和效率为代价的,所以它成不了大气候
认识问题吧。不过不知道作者是如何比较得出这样的结论的。
……
在 任何语言中,值的操作都可以归纳为以下 3 个方面。复制值 l 传递值 l 比较值
值操作啊。这个好象作者没什么错。hax解释下下?
css8错了,除了在文本代码里面,没这么存储的。可以建议看看IEEE标准,或者看引擎源代码。
一般不建议大家使用八进制数值直接量。因为很多时候,JavaScript 会误解析为十进制数值。
这种建议无意义的。用不用,是应用说了算。没有无聊到非得拿8进制来做事。再说,js里面,还有13、15、25进制的,有必要一一建议吗?
但是对于数值直接量来说,不能够直接调用 toString()方法,必须使用小括号强制运算数值直接量后,再调用该方法
……
如果字符串包含在双引号中,则字符串内可以包含单引号。反之,就不行了,但是在 VBScript 中就可以在单引号中包含双引号
“反之,就不行了”,这个你写个测试代码先?
布尔型(Boolean)……所占据的空间也是最小的(仅有 1 个字节)
这个……仍然是4个字节。其实——道理上来说,还不止4个字节。你最好看看引擎源码。
在对象中,当为属性设置值为 null 时,会提醒JavaScript 回收它们,无用也即无存在的价值,所以赋值 null 就等于判变量死刑(即删除变量)。
1、你前面在说“对象属性置null”,后面在说“变量置null“。这是两回事呀,二者没有推论关系的。
2、变量如果是指标识符,那么,“删除变量”这样的事情从来就不会发生。
3、很遗憾,全局变量不会被回收。因为保不齐什么时候在某个函数里面会来一个eval()语句,然后就访问到某个全局变量的标识符了。所以置null最多回收它的内存占用,但变量还是在的。
4、局部变量,是随闭包回收而回收的。
JavaScript 数组的结构比较固定,仅支持定义一维数组,虽然这简化了数组操作,但是
扩展性比较差,你 不能够使用JavaScript 定义多维数组。这 种固化的结构也显示了JavaScript
语言的柔弱性
你的“柔弱性”判断是有问题的,我看不出推论的依据何来。另外,许多多维数组的特性,可以通过交错数组来得到。这个在《程序设计语言》这本书里给出过解释。所以不必认为JS没有多维数组是“多么大的牺牲”。
下面代码定义了包含 5 个元素的空数组。var a = [,,,,];
存在引擎兼容性问题。好象前面有人解释过了。
如果属性值是函数,则该属性就成为对象的方法,读取这个特殊的属性值时,就必须附加小括号运算符
“读取这个特殊的属性值时”,其实不需要加括号运算符。反倒是“执行/调用”它时,才需要加的。这个,作者在概念的陈述上,真的不严谨。
没上下文,不讨论。
如果读者分析Google 网站的 JavaScript 程序,变量命名非常简洁,一般都为 1 或 2 个字母组成,这样做能够提高开发速度,便于书写
你能下载的Google网站的代码,是混淆过的。
如果你真要看Google的代码,你应该看看他们在Google map上公开的那几份。你就知道,他们的变量命名习惯不是你说的这样了。
如果我们为变量a 赋值为 null,则 JavaScript 垃圾回收器就知道这个变量也没有
用,于是把这个变量视为垃圾一并进行回收(栈区),也就是说,如果一个变量、属性、元
素或对象被赋值为 null,也就意味着它们是无用的垃圾了
1、回收与所谓“栈区”无关。
2、变量回收问题,前面讲过了。
3、属性不能被置null回收的。但可以通过delete语句来回收。
4、元素(array element)同上述第三条;而且数组元素可以通过splice()来删除和回收。
5、对象赋值为null?与变量同义吧?有必要区分么?
……