Leon's blog

关注: 开源&互联网, GTD with open source and Web

正在浏览标签为 javascript 的文章

先看这行代码: 挺神奇,哈? 这里有两件事情,首先当然是“==”这家伙引起了类型转换。 转换的规则是当两个对象a和b作比较时,如果一方是简单类型(假设是b吧),另一方是对象(假设是a);则把a类型转换成b的类型。前面的代码b(”,,,”)是字符串,简单类型,所以要求a(typeof Array是对象对吧)作类型转换到字符串。 另一件事情就是Array的类型转换,转换成字符串时,数组大概就是这样做的:首先把每一个元素转换成字符串,然后调用数组的join方法。既是本上a对象经历了这样的转变: 1. Array([],null,undefined,null) 2. Array(“”,””,””,””) 3. Array(“”,””,””,””).join() 4. “,,,” 最后变成了”,,,”,自然就返回true了。 同样的道理下面这行代码就不难理解了。 再看个变态点的: 其实这里主要是使用了逗号操作符的原因。MDN上时这样说逗号操作符的,从左往右计算,并返回右面的值。 所以(null,’cool’,false,NaN,4)的返回值就是4, 然后这个例子就变成,前面一个例子了。WTFJS。

Javascript有很多很好的特性,Douglas Crockford的JavaScript: The Good Parts是Javascript之美的最好的书籍。同时Javascript由于设计仓促,也有很多从语言角度来说非常傻b的现象。 网站WTFJS收集各种有趣的Javascript错误,供程序员茶余饭后谈资,未尝不是另一种美。 下面这段代码展示了Javascript对最大最小值的处理,导致了最大值比最小值小的现象。 看上去不错,只要你真拿他们来跟其他数值进行比较。但是用作不比较,还真不知道最大最小值有什么用途? 推荐书目:

ECMAScript里关于delete操作符的解释晦涩的很, 实在不是我能理解的. 有兴趣你可以去看看. 实际中使用中, 经常会碰到Javascript变量有时候能成功删除, 有时候却不掉成功删除的情况. 这篇Understanding delete牛文详细解释了, 为什么会这样, 什么样的变量能成功delete, 什么样的不能成功delete. 简而言之, 就是通过”声明“方式创建的变量不能成功删除, 通过”赋值“方式创建的变量能成功删除; 一但一个变量创建后, 它能不能被删除的属性将不会改变. 一个特例是通过eval()函数执行动态代码创建出来的变量,都是可以删除的. 如下面这段代码在Firefox/Chrome/Nodejs里的运行结果如下: Firebug的console里直接定义的变量(不包括在函数里定义的变量), 似乎是因为以eval()的方式在运行代码. 所以通过在Firebug的console里输入代码创建出来的变量,是可以删除的. Chrome等webkit系的浏览器的开发工具没有这个问题. 这一点在调试代码时可能会引起奇怪的现象.

在Web程序员应该知道的Javascript prototype原理里,说到了prototype chain. 但是有一点要特别注明一下, 那就是prototype chain只在对对象的方法和属性调用和读取时有效, 遵循沿着prototype查找方法和属性的规律; 但是在对对象属性进行赋值时, 并不遵循这一规律. 在对Javascript对象的属性进行赋值时, 原则是这样的: 1. 如果该对象本身有这个属性, 则对该属性赋值 2. 如果该对象本身没有这个属性, 则在该对象上新建一个该属性, 并进行赋值. (这时不会通过__proto__属性, 找该对象的prototype, 检查prototype上有没有该属性, 然后在prototype的属性上赋值.) 举个简单的例子: 看console里打出了的对象应该比较清楚. 用对象的数组写法可能更容易理解些.

有同事问了我几个和Javascript的类继承的小问题,我在也不太理解的情况下,胡诌了一通. 回来以后有些内疚, 反省一下, 整理整理Javascript的prototype的原理, 自己清楚点, 也希望对别人也有帮助. 首先js里面没有类这回子事情, 虽然class是js的保留字, 但是到现在也没派上任何用场. 在js里面, 几乎所有的东西都是对象, 函数也是对象, 所以函数可以赋值给别的变量. 另外js对象也可以用数组的方式访问, 也就是说访问obj1.something, 也可以写成obj1['something']. 在js里虽然没有类, 但是有一个在类编程里常用的的概念, Constructor构造器, 或者叫构造函数. 语法上Constructor跟普通的js函数没有区别, 但是Constructor前面加上new关键字就可以产生新的对象. 那么”new Constructor()”这样调用时到底做了什么事情呢? 1. js运行环境首先创建一个空对象 2. 把this变量指向这个对象 3. 把__proto__指向这个构造器的prototype属性 4. 通过this把属性和方法加在这个对象上 5. 最后会把this指向的对象return出来(当然你也可以显示的return别的对象,这是情况跟我讨论的有点不一样) 这里有2个概念比较重要, 第一是Constructor的prototype属性, 它是Constructor的一个保持共享属性和方法的对象. 二通过该Constructor生成的对象的__proto__属性, 它指向了那个prototype对象. 对象的Constructor可以通过该对象的constructor属性获得. 我们定义一个简单的Constructor Demo(), 然后通过他生成一个aDemo对象, 在Chrome的console里把aDemo打出来看到的结果是这样的,这是我们能很清楚的看出这种关系. 换一种写法, 其实跟前面没多大区别, 不过这一次f2()不在创建出来的对象上, 而是在对象的__proto__指向的构造器DemoB上. 这样的好处是当使用DemoB创建很多对象时, 比较节省内存. js的prototype搜索链 prototype Chain js的运行环境是这样使用构造器的prototype的. 当我们对第一个对象调用其方法时, [...]