日期:2014-05-16  浏览次数:20375 次

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值,其他均属于对象. 其中由于数字,字符串和布尔值类型包含了方法,所以'貌似'是对象,但它们均是不可变的。
    ?? Javascript 中的对象是可变的键-值集合。在Js中,数组是对象,函数是对象,正则表达式是对象。当然,简单对象本身也是对象. 对象是属性的容器,其中每个属性都拥有名字和值,属性的名字可以是包括空字符串在内的任意字符串。属性值可以是除undefined之外的任何值。JavaScript 中的对象是无类别的,它对新属性的名字和值没有约束。对象适合用于收集和管理数据.对象可以包含其他对象,所以它们可以容易地表示成树形或图形结构。
  • 对象字面变量提供了一种非常方便地创建新对象值的表示法。
    var empty_object = {};
    var stooge = {
    	"first-name" : "Jerome",
    	"last-name" : "Howard",
    	age : 46
    };
    ??? 如果属性名是一个合法的Javascript 标识符并且不是保留的关键字,则并不强制使用双引号来括住属性名。这里由于 '-' 是非法的变量字符,所以"first-name" 是必须的,而如果对于 first_name, 可以选择不使用双引号.
    ??要检索对象中包含的值,可以在对象后面使用["属性名"]来获取。如果属性名是合法的JS标识符,那么可以使用'.'进行检索.一般情况下应该优先使用 '.' 导航法. 如果尝试检索一个并不存在的成员,将会返回一个undefined值. 此时可以使用 || 运算符来填充默认值.
    window.alert(stooge.unknownProperty); // undefined
    window.alert(stooge.unknownProperty || "未知值!"); // 未知值!
    
    ?
    ??? 再次提醒,JS中逻辑判断并不是简单地判断Boolean值,而是针对所有简单类型(null,undefined等)和对象.进行布尔判断时: false, null, undefined, 空串(''), 数字0, 数字NaN 均被看做 不成立。其他情况均可以执行。尝试检索一个undefined值将会导致TypeError异常。这可以通过&&运算符来避免错误.
    stooge && stooge.func && stooge.func();
    ?
  • 对象通过引用来传递。它们永远不会被拷贝(!).
    var x = stooge;
    window.alert(x.age === stooge.age); // true
    
    var 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 = undefined
    window.alert(another_stooge.willBeDelete);
    // 无效,profession 是原型链中的属性.
    delete another_stooge.profession; 
    window.alert(another_stooge.profession);
    ?还有一种值得注意的情况是删除对象的属性有可能将原型链中被隐藏的属性暴露出来.
    // 此时原型链中的profession 将被隐藏,因为向上递归查找属性时将会优先返回 对象自身的profession.
    another_stooge.profession = "actress"; 
    // 删除掉对象自身的profession,此时查找profession 将会返回原型链中的profes