JavaScript: The Good Parts 读书笔记(一)
一.基础特性
在浏览器中,每个<script> 块都被解释成一个编译单元,因为缺少链接器。Javascript 把它们一起抛入一个公共的全局名称空间中(window).进行布尔判断时: false, null, undefined, 空串(""), 数字0, 数字NaN 均被看做 不成立javascript 的switch 语句允许case 字符串for in 语句会枚举一个对象的所有属性名. 当需要检测一个属性是对象自身的还是从原型处继承的时候. 可以通过Object.hasOwnProperty(variable)来进行判断. for(myVar in obj){ if(obj.hasOwnProperty(myVar)){ ... } }?for in 语句可以用来遍历一个对象中所有的属性名(包括原型中的).但属性名出现的顺序是不确定的,因此要对任何可能出现的顺序有所准备。如果需要保证顺序,应该使用 for 语句并搭配hasOwnProperty判断.这样就不必担心查找出原型链中的属性了。typeof 运算符产生的值有 'number','string','boolean','undefined','function'和'object'.javascript 的简单类型包括数字,字符串,布尔值, null值和undefined值,其他均属于对象. 其中由于数字,字符串和布尔值类型包含了方法,所以'貌似'是对象,但它们均是不可变的。var empty_object = {};var stooge = {"first-name" : "Jerome","last-name" : "Howard",age : 46};??? 如果属性名是一个合法的Javascript 标识符并且不是保留的关键字,则并不强制使用双引号来括住属性名。这里由于 '-' 是非法的变量字符,所以"first-name" 是必须的,而如果对于 first_name, 可以选择不使用双引号.window.alert(stooge.unknownProperty); // undefinedwindow.alert(stooge.unknownProperty || "未知值!"); // 未知值!?
stooge && stooge.func && stooge.func();?对象通过引用来传递。它们永远不会被拷贝(!).
var x = stooge;window.alert(x.age === stooge.age); // truevar a = {}, b = {}, c = {}; // a ,b 和 c 每个都引用一个不同的空对象.a = b = c = {}; // a ,b 和 c 都引用同一个空对象.Javascript 包括一个原形(Prototype)特性.允许某个对象继承另一对象的属性。正确地使用它能减少对象初始化的时间和内存消耗. 每个对象都连接到一个原形对象,并且它可以从中继承属性。所有通过字面变量创建的对象都自动连接到了 Object.prototype 上。利用这里特性,可以创建一些帮助方法:// 当创建一个新对象时,你可以选择某个对象作为它的原型。下面给Object添加一个beget方法.// 该方法创建一个使用原对象作为其原型(prototype)链的新对象(简单地继承).if(typeof Object.beget !== 'function'){Object.beget = function(obj){var fun = function(){};fun.prototype = obj;return new fun();};}var another_stooge = Object.beget(stooge);// 利用原型链继承。window.alert(another_stooge["first-name"]);// 尝试对新对象的修改将不会反射到源对象中(stooge). another_stooge.age = 24;???原型链只有在检索值的时候才会被用到,如果我们尝试去获取对象的某个属性值,且该对象没有此属性名,那么Javascript 会试着从原型对象中获取该属性,该过程将会一直向上递归到Object.prototype 为止. 如果想要的属性值完全不存在于原型链中,那么结果就是 undefined值,这个过程称为 委托 .stooge.profession = 'actor';window.alert(another_stooge.profession);?Javascript 中delete 操作符可以用来删除对象自身的属性。但他不能删除原型链中的任何对象.
another_stooge.willBeDelete = {};delete another_stooge.willBeDelete; // another_stooge.willBeDelete = undefinedwindow.alert(another_stooge.willBeDelete);// 无效,profession 是原型链中的属性.delete another_stooge.profession; window.alert(another_stooge.profession);?还有一种值得注意的情况是删除对象的属性有可能将原型链中被隐藏的属性暴露出来.// 此时原型链中的profession 将被隐藏,因为向上递归查找属性时将会优先返回 对象自身的profession.another_stooge.profession = "actress"; // 删除掉对象自身的profession,此时查找profession 将会返回原型链中的profession.delete another_stooge.profession; window.alert(another_stooge.profession); // actor?javascript 可以很随意地定义全局变量.不幸的是,全局变量消弱了程序的灵活性,所以应该避免. 最小化使用全局变量的一个方法是在你的应用中只创建唯一一个全局变量:
var Application = {}; // 该变量此时变成了你的应用的容器.Application.environment = {path : "http://localhost:8080/application/"};Application.version = "1.0";? 只要把多个全局变量都整理在一个名称空间下,就可以显著的降低与其他应用程序,组件或类库的相互影响.另一个方法是使用闭包来进行信息隐藏.