《JavaScript语言精髓与编程实践》读书笔记--基础篇

一、弱类型语言:
      JavaScript   是弱类型语言。但所谓言 弱类型语言 ,只代表该语言在表达式运 算中不强制校验运算元的数据类型,而并不代表该语言是否具备类型系统。
二、 JavaScript 识别6 种数据类型,并在运算过程当中自动处理语言类型的转换。
  2.1   6种数据类型:
      undefine、number、string、boolean、function、object, typeof   运算老是以字符串形式返回上述   6   种类型值之一。
  2.2   变量的两种类型:
     1)基本类型在内存中具备固定的大小,而引用类型则不一样。例如,对象能够具备任意的长度,无固定大小。数组也是。
     2)基本类型变量存的是数据的具体值,而引用类型变量保存的是值的引用。   
      基本类型: undefine、number、boolean string
     引用类型: function、object
三、NaN 值:
      至少表面上来看, 一个值应该与其自身“ 等值   / 全等”。但事实上,在 JavaScript   中存在一个例外:一个   NaN   值,与自身并不等值,也不全等。
四、 空字符串用做对象成员。
      JavaScript   中也能够用一对不包含任意字符的单引号与双引号来表示一 个空字符串(   Null String ),其长度值老是为 0 。比较容易被忽视的是,空字符 串与其它字符串同样也能够用做对象成员。
object{
          '':100;
     }
 alert('');  //100
五、相等运算符 == 和等同运算符 === 。
     1) === 运算符是等同运算符,它采用严格的同一性定义检测两个运算数是否彻底等同。
     2)== 运算符是相等运算符,它采用比较宽松的同一性定义(即容许进行类型转换)检测两个运算数是否相等。
下面的规则用于断定   ===  运算符比较的两个值是否彻底相等:
     1.若是两个值的类型不一样,它们就不相同。
     2.若是两个值的类型是数字,并且值相同,那么除非其中一个或者两个都是NaN(这种状况它们不是等同的),不然他们是等同的。值NaN永远不会与其余的任何值等同,包括它自身。
     3.若是两个值都是字符串,并且在串中的同一位置上的字符彻底相同,那么它们就彻底等同。若是字符串的长度或内容不一样,它们就不是等同的。
     4.若是两个值都是布尔值true,或者两个值都是布尔值false,那么它们等同。
     5.若是两个值引用的是同一个对象,数组或函数,那么它们彻底等同。若是它们引用的是不一样的对象(数组或函数),它们就不彻底等同,即便这两个对象具备彻底相同的属性或两个数组具备彻底相同的元素。
     6.若是两个值都是null或都是undefined,它们彻底相同。

下面的规则用于断定 ==运算符比较的两个值是否相等:
     1.若是两个值具备相同的类型,那么就检测它们的等同性。若是这两个值彻底相同,它们就相等。若是它们不彻底相同,则它们不相等。
     2.若是两个值的类型不一样,它们仍然可能相等。用下面的规则和类型转换来检测它们的相等性:
        2.1 若是一个值是null,另外一个值是undefined,它们相等。
        2.2 若是一个值是数字,另外一个值是字符串,把字符串转换为数字,再用转换后的值进行比较。
        2.3 若是一个值是true,将它转换成1,再进行比较。若是一个值为false,把它转换成0,再进行比较。
        2.4 若是一个值是对象,另外一个值是数字或者字符串,将对象转换成原始类型的值,再进行比较。
        2.5 其余的数值组合是不相等的。
六、delete 运算符:
  6.1  delete   能够删除不少东西 ( 包括对象成员和数组元素   ) ,但它不能删除:
      1) var   声明的变量;
      2)直接继承自原型的成员。
var obj = {
          method : function() { },
          prop : 1234
     }
     golbal_value  =  'abcd';
     array_value = [0,1,2,3,4];
     function testFunc() {
          value2 = 1234;
          delete value2;
     }
     // 调用testFunc() 函数,函数内部的delete 用法也是正确的
     testFunc();
     // 如下四种用法都是正确的
     delete obj.method;
     delete obj[ 'prop' ];
     delete array_value[ 2 ];
     delete golbal_value;

     delete 不能删除继承自原型的成员。但若是你修改了这个成员的值,你仍然能够删除它,这将使它恢复到原型的值。关于这一点的真相,是 delete 运算事实上是删除了实例的成员表中的值。 数组

  6.2  delete   仅在删除一个不能删除的成员时,才会返回   false   。其 它状况下,例如删除不存在的成员,或者继承自父代类/原型的成员,都 将返回 true
function MyObject() {
     }
     MyObject.prototype.value = 100;
     // 该成员继承自原型,且未被重写, 删除返回true.
     // 因为delete 操做不对原型产生影响, 所以obj1.value 的值未变化.
     var obj1 = new MyObject();
     alert( delete obj1.value );
     alert( obj1.value );
     // 尝试删除Object.prototype ,该成员禁止删除, 返回false
     alert( delete Object.prototype );
七、对象及其成员的检查:
  7.1   in 运算。
  7.2  instanceof : insta nceof   将会检测类的继承关系。
// 声明构造器
     function MyObject( ) {
     // ...
     }
     // 实例建立
     var obj = new MyObject( );
     // 显示 true
     alert( obj  instanceof  MyObject );     
     function MyObjectEx( ) {
     // ...
     }
     //原型链
     MyObjectEx.prototype = new MyObject( );
     // 实例建立
     var obj2 = new MyObjectEx(  );
     // 检测构造类, 显示 true
     alert( obj2 instanceof MyObjectEx );
     // 检测父类, 显示 true
     alert( obj2 instanceof MyObject );
  7.3   propertyIsEnumerable  的一个实现版本, 该方法是不检测对象的原型链的
    //code from Qomo Project.
    Object.prototype.propertyIsEnumerable = function(proName) {
          for ( var i in this ) {
               if ( i == proName ) break;
          }
          if ( i != proName ) return false;
          // if clone from prototype, return false.
          return this[ proName ] !== this.constructor.prototype[proName];
     }
      当某个对象成员不存在, 或它不可列举时, 则对该成员调用 propertyIsEnumera ble() 方法将返回 false   —— 比较常见的状况是,   JavaScript   象的内置成员是不能被列举的。
var obj = new Object();
     // 不存在'aCustomMember', 显示false
     alert( obj.propertyIsEnumerable('aCustomMember') );
     // 内置成员不能被列举,这种状况下,你能够用  in 运算检测到该成员,但不能用 for..in 语句来列举它。
     alert( obj.propertyIsEnumerable( 'constructor' ) );
八、缺省对象的指定:with语句。
// 示例1: 存取对象成员
     var obj = new Object( );
      obj.value = 100;
     // 示例2: 访问(全局的)对象或值
     value = 1000;
     with ( obj ) {
           value *= 2;
     }
     alert( obj.value );  //200
     alert( value );  //100
九、
//声明对象直接量
     var obj = {
          v1: 1,
          v2: 2,
          v3: 3
     }
十、[ ] 的二义性: 数组声明、 数组下标运算符、对象成员的存取运算符。
      a = [ [ ][ 100 ] ];  // 第一个数组为空数组, 第二个数为任意数值,都将获得[ undefined ]
      a = [ [ 1, 2, 3 ][ 2 ] ]; // 第一个数组有三个元素,所以arr[2] 是存在的,故而获得[ 3 ]
      a = [ [ ][ ] ];  // 第一个数组为空,是正常的;但第二个做为下标运算时缺乏索引,故语法错
十一、语法做用域
     分表达式(一级)、语句、函数、全局四级
      1)语法做用域是互不相交的。正是做用域互不相交的特性构造了代码结构化的层 次,并消除了一些错误隐患。
      2) 语法做用域间能够存在平行或包含关系。 高级别能够嵌套低级别的语法做用 域,反之则不成立。
      3)高级别的流程变动子句(或语句)能够跨越低级别的做用域,反之则不行。
十一、变量做用域

     表达式级、函数(局部)级、全局,JavaScript 不存在语句级别的变量做用域。在全局范围内使用 for 循环的同时声明变量,该变量是全局变量。 函数

十二、因为JavaScript 是动态语言,所以它只能依赖“变量做用域”来实现封装特性。 this

1三、对象的多态性被转换为运行期的动态特性—— 例如咱们能够动态地添加对象的方法/成员,使它看起来象是某个对象。
1四、类抄写与原型继承:
     1) 类抄写时成员访问效率更高,但内存占用较大;而原型继承反之。
     2) 类抄写不依赖内部原型链来维护继承关系,所以也不能经过   instanceof   来作这 种检测;原型继承却能够在   new   运算时维护这种继承关系,也能够检测之。
1五、非惰性求值
/**
* 示例1:在参数中使用表达式时的求值规则
*/
var i = 100;
alert( i+=20, i*=2, 'value: '+i );  //120
alert( i );  //240
1六、callee
      JavaScript 1.2   开始使   arguments   对象拥有一个成员: callee ,该成员 老是指向该参数对象   (Arguments) 的建立者函数。因为 arguments   老是在函数内 部能够直接访问,所以也就老是能够在函数内部识别“我是谁”。
      这样一来,不管是否匿名,函数的递归就老是能够写成:(callee 解决了匿名递归的问题
void function() {
     // ...(略)
     arguments.callee();
     }();
1七、caller  
    caller  Function  的一个成员,指向函数调用者。
1八、null是一个object实例(空对象),  typeof null的值是object。
相关文章
相关标签/搜索