《JavaScript高级程序设计》序、Chapter 1/2/3/4

考虑到本书的发行时间,对于一些兼容性的问题按照先按照本书的说法进行记录。

这里记录的是对《JavaScript高级程序设计》第三版一书的纯主观的理解。

Chapter 1 JavaScript简介、发展情况 go

Chapter 2 HTML中使用JS(插入JS及注意事项) go

Chapter 3 JS基本概念(语法、数据类型、语句、函数基本) go

Chapter 4 变量、作用域、内存问题(理解JS的作用域机制)go

Chapter 1(JavaScript简介、发展情况)

  • javaScript是为了减轻服务端的负担、减少数据递交浪费的时间而出现的,逐渐发展成比较系统的面向对象的语言、实现交互等功能。
  • javaScript的演变经历了公司之间的竞争,最终在W3C等标准协会的介入下形成标准。
  • javaScript = ECMAScript + DOM +BOM
  • ECMAScript规定了语言部分。
  • DHTML->DOM:将Web页面映射成节点(对象)树,便于维护和动态处理,实际上,DOM作为API,不仅适用于Web。
  • DHTML、 DOM HTML、DOM core
  • BOM:对浏览器窗体的控制等,在HTML5中有形成标准的希望。

Chapter 2(HTML中使用JavaScript)

  • <script>可嵌入脚本或者引入外部脚本,也可以在HTML标签中书写简单的javaScript。
  • 注意对于type的设置,可以不使用,或者设置成“text/javascript”-->总之要确保服务器正确的返回MIME。
  • 下载和执行的顺序问题:
    •   一般按照引入的顺序执行,所以放在头部会影响到页面内容的加载,建议放在body标记的最后
    • defer属性:延迟脚本。先下载,后执行,在页面加载完毕之后执行。理论上,延迟脚本之间会按照顺序执行,并会在DOMContentLoaded事件触发之前执行。然而实际上并不一定,所以建议只引入单个延迟脚本。
    • async属性:顾名思义,异步脚本。避免页面等待脚本的下载和执行,异步加载其余的内容,异步脚本之间不一定按照顺序执行,也不一定会在DOMContentLoaded时间触发之前执行。
    • 二者都只对外部脚本有效。
  • XHTML(XML):对JS的书写要求更加的严格,可采用<![CData[...]]>减轻对特殊字符的转义的工作量,在脚本中使用//<![CData[...//]]>可实现平稳退化。
  • 对于不支持或者禁用了JS的HTML,用<noscript>标记平稳退化,或者用<!-- ... //-->进行平稳退化(不推荐,因为一般浏览器都支持JS了,想要实现平稳退化,可考虑其他更加有效严谨的手段,参照《JavaScript DOM编程艺术》)
  • 文档模式:混杂模式、标准模式(HTML5)--->准标准模式,后两者的差距比较下。
  • 本书推荐使用外部脚本。

Chapter 3 基本概念(语法、数据类型、语句、函数)

ECMAScript 3 ---> ECMAScript 5

第二次阅读本书,理解起来比第一次看的时候清晰、容易了许多。

  • 语法
    • 标识符:用作变量、函数、属性的名称
    • 关键字:语言本身使用的。
    • 保留字:将来可能用作关键字的。
    • 变量、字面量:前者为值提供一个占位符,后者就是值本身。
  • 关键字和保留字:注意ES3和ES5的不同之处,后者的一般模式和严格模式又有不同。注意eval和arguments的现实。
  • 变量:var。弱类型。占位符:不过还是不建议在使用的过程中更改数据类型。
  • 数据类型
    • 5个基本类型(null\undefined\boolean\number\string)、1个复杂数据类型(引用类型,object)
    • typeof返回字符串。主要用来区分具体的基本类型。但会对函数提供特殊的“function”,对于null则认为是object。
    • 对于未定义的变量,可以用typeof表示为“undefined”,但无法进行其他的具体操作。而在严格模式下,连typeof操作符也失效。
    • null:空对象。表示占位但为赋值(这里和undefined有微妙的不同)。更用来表示未赋值的对象,“空指针”。
    • boolean:Boolean()函数
    • number类型
      • 既可以表示整数,也可以用来表示浮点数。既可以表示十进制,也可以表示其他进制(但在ES3、ES5有差异,一般模式和严格模式也有差异)
      • 避免浮点数的计算和比较,因为说到底只是计算机的近似处理。
      • 特殊的数值:Infinity/-Infinity/NaN -- isFinity()函数、isNaN()函数---NaN与谁的不相等,包括自身。
      • 数值转换(转型函数):Number()函数、parseInt()函数、parseFloat()函数。
    • string类型
      • 字符一旦创建就不能更改,我们眼中的更改实际上经历了后台对字符串的销毁和再赋值等操作。
      • toString()方法和String()函数。后者功能略多些,可以处理undefined和null。
      • 区分函数String(value)和方法value.toString()
    • 其他类型向数值等进行默认的转换:有普遍的规律。一般会调用Number()转型函数进行转换。对于Object类型,会调用valueOf()方法和toString()方法,前者优先于后者。
  • 操作符
    • ·一般的操作符的使用,都会涉及到数据类型之间的转换,常见的转换有
      • 向数值的转换
      • 向字符串的转换
      • 向布尔值的转换
    • 第一次提到副效应:变量的值在语句被求值之前就改变了(如前置递增、递减操作符)
    • 位操作符:注意实际上存储的是64位,但一般按照32位进行处理。貌似较少用到。
    • 布尔操作符:逻辑与或非。或和与都是短路操作。以“与”操作为例,当第一个操作数为false,就“短路”---不再考虑第二个操作数,直接返回false;书中有复杂的对于两个操作数有object类型的考虑,考虑到object的转换为布尔类型均为true,实际上这个规律与与、或操作的短路特点有关。
  • 语句
    • for-in语句:常用来枚举对象属性,并以此为接口进行更多的操作。
  • 函数
    • 参数:JS中形参传入后将被放到函数内部的一个对象数组arguments[]中作为局部变量,因此JS中函数声明的参数个数(可以通过调用函数的length属性获得)与实际的参数个数(调用arguments.length获得)没有必然的关系。
    • 由于上述原因,再加上JS函数名实际上只是一个引用,JS函数没有“函数签名”的概念(同名函数,参数不同视作不同函数)
    • 因此,JS函数没有重载的说法,但可以模拟重载。
      • 没有重载,体现在:若声明复数个数的同名函数,即使参数不同,最后的函数声明将之前的覆盖。
      • 模拟重载,可以这么做:对不同的参数个数用if-else语句书写不同的处理语段,以此进行模拟。
  • ES的参数传递的都是值,而非引用(在chapter 4进一步说明)
  • 自由的语言

Chapter 4 变量、作用域、内存问题

  • 基本类型和引用类型
    • 只有引用类型可以动态创建属性(基本类型想要访问方法和属性,得借助于基本包装类型)
    • 基本类型占据固定大小的空间(栈内存),引用类型则是堆内存。
    • 在进行访问的时候,基本类型按照值访问,而引用类型按照引用访问(实际上,JS不允许直接访问内存,所以引用类型只能依靠指针访问)
    • 同样,在进行复制的时候,基本类型创建副本。引用类型同样创建副本,然而这个副本实际上是指向某个内存的引用的副本。
    • 在向函数传递参数的时候,无论基本类型还是引用类型,统一按值传递。前者比较好理解,引用类型的按值传递可以依靠下面的例子理解:
function setName(obj){
    obj.name = "Nicholas";
    obj = new Object();
    obj.name = "Peter";   
}

var person = new Object();
setName(person);
alert(person.name); //实际上弹出的是"Nicholas"
    • 类型检测(typeof以及instanceof):
      • 基本类型的检测依靠typeof操作符
      • 引用类型可以通过检测所属的类型实例进行检测,即,使用instanceof操作符
      • 由于所有的引用类型最终都是Object的实例,所以对于引用类型x,x instanceof Object始终会返回true
      • instanceof用于对具体的引用类型进行检测,所以如果这个操作符后所跟的不是引用类型,则会返回false
      • 正则表达式的typeof:按照规定,含有[[call]]方法的对象都会返回function。根据浏览器而异。

 

  • 执行环境和作用域
    • 通过下图理解以下代码的作用域
    • var color ="blue";
      function changecolor(){
          var anotherColor = "red";
          function swapColor(){
              var tempColor = anotherColor;
              anotherColor = color;
              color = tempColor;
      }
      }
      
      changeColor();

    • 由某一个对象来代表当前的执行环境,这个对象下又存储着一系列的变量(对象)和方法,如浏览器的window对象,函数内部的arguments对象(“面向对象”)
    • 执行环境在该函数执行完毕后销毁,从栈中退出,将控制权交还给上一个执行环境。
    • 作用域链随着执行环境的创建而创建,为了可以有序合理的对函数和变量进行访问。
    • 标识符的解析:如图,沿着作用域链向上搜索,当搜索到匹配的变量后即停止,不再继续搜索(即使父环境中可能仍然有符合条件的变量)。这就决定了不同环境对变量的访问权问题,以及JS中变量的覆盖问题。
    • 延长作用域链的方法:try-catch,with语句。
    • JS没有块级作用域,var声明的变量属于最近的环境。
  • 垃圾收集
    • JS自动对内存进行管理,进行垃圾收集,不需要程序员过于操心。
    • 垃圾收集机制按照周期启用,收集标记为待销毁的变量。
    • 实际上,对于局部变量,会在退出该局部环境的时候自动销毁。
    • 两种方式:标记清除、引用标记。
    • 标记清除:对于不使用的变量做上标记,以便之后清除。
    • 引用标记:有循环引用的问题。在BOM中仍然存在。
    • 解除引用:为了避免循环引用,同时考虑到内存管理的问题。建议必要的时候,对无法自动标记的变量打上标记:variable = null;解除引用,以待垃圾收集。
posted @ 2017-10-15 14:52  nebulium  阅读(270)  评论(0编辑  收藏  举报