JavaScript 知识点总结

第 1 章 JavaScript简介

1.1 JavaScript简史

  • 前端三层
    • HTML——结构层从语义的角度描述页面的结构
    • CSS——样式层从装饰的角度描述页面的样式
    • JavaScript——行为层从交互的角度描述页面的行为
  • JavaScript 作用:数据验证、读写HTML元素、与浏览器窗口及其内容的交互效果、创建cookies、网页特效、WEB游戏制作、基于Node.js技术进行服务器端编程

1.2 JavaScript实现

  • ECMAScript
    • 规定了语法、类型、语句、关键字、保留字、操作符、对象
    • 对实现上诉标准规定的各个方面内容的语言的描述
  • 文档对象模型(DOM)
    • 针对XML但经过扩展用于HTML的应用程序编程接口(API)
    • DOM级别
      1. DOM 1级:DOM HTML、DOM Core
      2. DOM 2级:DOM 视图/事件/样式/遍历和范围
      3. DOM 3级:DOM 加载和保存/验证
      4. 其他标准:SVG、MathML、SMIL
  • 浏览器对象模型(BOM)
    • 弹出新浏览器窗口的功能
    • 移动、缩放和关闭浏览器窗口的功能
    • 提供浏览器详细信息的 navigator 对象
    • 提供浏览器所加载页面的详细信息的 location 对象
    • 提供用户显示器分辨率详细信息的 screen 对象
    • 对 cookies的支持
    • 像 XMLHttpRequest 和IE的 ActiveXObject 这样的自定义对象

1.3 JavaScript版本

第 2 章 在HTML中使用JS

2.1 script元素

2.1.0 标签属性

  • async:表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或 等待加载其他脚本。只对外部脚本文件有效。
  • charset:表示通过 src 属性指定的代码的字符集。
  • defer:表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。
  • language:已废弃,原来用于表示编写代码使用的脚本语言。
  • src:表示包含要执行代码的外部文件。
  • type:可看成language的替代属性,表示编写代码使用的脚本语言的内容类型(MIME类型),非必需,若无指定此属性,则其默认值仍为text/javascript。

2.1.1 标签的位置

​ JavaScript是依托于HTML中的脚本,代码位于标签之间,不限脚本使用数量

  • 放在元素中:会导致浏览器在呈现页面时出现明显的延迟。
  • 放在元素中页面内容的后面:可加快显示速度,推荐。

2.1.2 延迟脚本

​ 使用defer属性用于表明脚本在执行时不会影响页面的构造,脚本会被延迟到整个页面都解析完毕后再运行,即在遇到标签后再执行。

2.1.3 异步脚本

​ 使用async属性是不让页面等待两个脚本下载和执行,从而异步加载页面其他内容。

2.2 嵌入代码与外部文件

​ 使用外部文件引入比嵌入代码更优,具有可维护性、可缓存、适用未来的优点。

  • 引用方法
    • 头部引用:
    • 体部引用:
    • 外部引用:

2.3 文档模式

  • 混杂模式(quirks mode)
  • 标准模式(standards mode)

2.4 noscript元素

​ 即当早期的浏览器不支持 JavaScript 时如何让页面平稳地退化。

第 3 章 基本概念

3.1 语法

  • 区分大小写

  • 标识符

    • 第一个字符必须是一个字母、下划线(_)或一个美元符号($)
    • 其他字符可以是字母、下划线、美元符号或数字
  • 注释

    • // 单行注释
    • /* 块级注释 */
  • 严格模式

    ​ 开启严格模式,ECMAScript 3中的一些不确定的行为将得到处理,而且对某些不安全的操作也会抛出错误。开启方法如下:

    在顶部添加代码: "use strict"; 
    在函数内部的上方添加代码: 
    function doSomething(){
      "use strict";
      //函数体
    } 
    
  • 语句:以一个分号;来结尾。

3.2 关键字和保留字

  • 关键字

    break     do          instanceof  typeof  default
    case      else        new         var     if
    catch     finally     return      void    throw
    continue  for         switch      while   delete
    in            function    this        with    try
    debugger*    
    
  • 保留字(ver5,*为非严格模式下)

    class*    enum*   extends*    super*  const*  export* import*
    abstract  short       debugger    synchronized    let
    boolean       interface   static      implements      static
    byte      long        protected   int             implements
    char      final       native      volatile        protected
    float     package     throws      double          yield
    goto      private     transient   public          private
    package       public      interface
    

3.3 变量

​ ECMAScript的变量为松散类型,变量(Variables)相当于一个容器,可用来保存任何类型的数据。即每个变量仅是一个用于保存值的占位符。定义变量时要使用 var 操作符,后跟变量名(标识符)。

var message; //定义了一个名为message的变量
var message = "hi"; //定义message变量的同时赋值保存一个字符串值"hi"
var message = "hi",
    found = false,
    age = 29;       //使用一条语句定义多个变量

注意:

  1. 用var声明的未赋初值的变量,值会提前被设定为undefined(未定义),之后可以保存任何值
  2. 用 var 操作符定义的变量将成为定义该变量的作用域中的局部变量,如果在函数中使用 var 定义一个变量,那么这个变量在函数退出后就会被销毁
  3. 对已经赋值的变量重新声明,该变量的值不会丢失

3.4 数据类型

​ ECMAScript中包含6种数据类型(基本×5、1种特殊即Object)

3.4.1 typeof 操作符

​ typeof 用来检测给定变量的数据类型,如下:

var message = "some string";
alert(typeof message);     // "string"
alert(typeof(message));    // "string"
alert(typeof 95);          // "number"

"function"函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过 typeof 操作符来区分函数和其他对象是有必要的

3.4.2 Undefined 类型

​ Undefined 类型只有一个值,即在使用 var 声明变量但未对其加以初始化时, 这个变量的值就是undefined

var message;
alert(message == undefined); //true
  1. 定义为undefined的变量与尚未定义的变量是不一样的
  2. 对未初始化和未声明的变量执行 typeof 操作符都会返回 undefined 值

3.4.3 Null 类型

​ Null 类型只有一个值,表示一个空对象指针

var car = null;
alert(typeof car); // "object"
  1. 使用typeof操作符检测null值时会返回"object"
  2. 如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为 null 而不是其他值,这样一来只要直接检查 null 值就可以知道相应的变量是否已经保存了一个对象的引用
  3. 实际上, undefined 值是派生自 null 值的
  4. 可以通过将变量的值设置为 null 来清空变量

3.4.4 Boolean 类型

​ 布尔类型只有两个字面值——true和false,但ECMAScript中所有类型的值都有与这两个 Boolean 值等价的值。要将一个值转换为其对应的 Boolean 值,可以调用转型函数 Boolean() ,如下例所示:

var message = "Hello world!";
var messageAsBoolean = Boolean(message);
//字符串message被转换成了一个布尔值,该值被保存在messageAsBoolean变量中
数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 "" (空字符串)
Number 任何非零数字值(包括∞) 0和 NaN
Object 任何对象 null
Undefined N/A(不适用) undefined

3.4.5 Number 类型

  • 整数字面量

    十进制:最基本的数值字面量格式,直接在代码中输入
    var intNum = 55;
    var intNum = -55;
    
    八进制:前缀为0、0O、0o,若以0为前缀,超出取值范围会直接转换微十进制显示;若以0o/0O为前缀,超出取值范围直接显示报错
    var octalNum1 = 070; // 八进制的56
    var octalNum2 = 079; // 无效的八进制数值——解析为十进制的79
    var octalNum3 = 0o89; // 显示出错
    
    十六进制:前缀为0x、0X,超出取值范围会直接报错,字母可大小写
    var hexNum1 = 0xA; // 十六进制的10
    var hexNum2 = 0x1f; // 十六进制的31
    var hexNum3 = 0x5g; // 显示出错
    

    进行算术计算时,所有八进制和十六进制表示的数值都将被转换成十进制数值

  • 浮点数字面量:所有浮点数都是以十进制表示

    var floatNum1 = 1.1;
    var floatNum2 = 0.1;
    var floatNum3 = .1; // 有效,但不推荐,表示0.1
    var floatNum4 = 1.; // 小数点后面没有数字——解析为1
    var floatNum5 = -.618; //表示-0.618
    var floatNum = 10.0; // 整数——解析为 10
    var floatNum = 0.4235689e5; // e5表示×10^5,结果依然为42356.89
    

    浮点数值的最高精度是17位小数,但有些浮点数值计算会产生舍入误差的问题,这是使用基于IEEE754数值的浮点计算的通病,也会出现在其他语言上

  • 特殊值

    无穷:计算机计算能力有限,若大于或小于某个临界点(这个值是5e-324,存在Number.MAX_VALUE中),计算机没法算出具体数字,会直接输出是一个Infinity或-Infinity,无穷值无法继续参与下一次的计算
    console.log(-8.6e9876505676054);  //显示-Infinity
    
    NaN:非数值(Not a Number),用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误),但它依然是一个数字字面量
    alert(NaN == NaN); //NaN与任何值都不相等,解析为false
    alert(isNaN(NaN)); //true
    alert(isNaN(10)); //false(10是一个数值)
    alert(isNaN("10")); //false(可以被转换成数值10)
    alert(isNaN("blue")); //true(不能转换成数值)
    alert(isNaN(true)); //false(可以被转换成数值1)
    
    1. 使用 isFinite() 函数可以确定一个数值是不是有穷数
    2. 使用 isNaN() 函数可以确定这个参数是否“不是数值”,在接收到一个值之后,会尝试将这个值转换为数值

3.4.6 String 类型

  • 用于表示由零或多个16位Unicode字符组成的字符序列(即字符串)

    var firstName = "Nicholas";
    var lastName = 'Zakas';
    var 1stName = 'Nicholas"; // 语法错误(左右引号必须匹配)
    
  • 字符字面量:也叫转义序列,用于表示非打印字符或其他用途

    var text = "This is the letter sigma: \u2764."; //该转义字符为❤
    alert(text.length); //任何字符串的长度可通过访问其length属性取得,输出28
    

    字符串一旦创建,它们的值就不能改变,要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量,如下

    var lang = "Java"; 
    lang = lang + "Script"; 
    /* 把lang的值重新定义为"Java"与"Script"的组合,即"JavaScript" */
    

3.4.7 Object 类型

  • ECMAScript中的对象是一组数据和功能的集合

    对象可通过执行new操作符后跟要创建的对象类型的名称来创建,而创建Object类型的实例并为其添加属性和方法,就可以创建自定义对象
    var o = new Object();
    如果不给构造函数传递参数,即不传递参数的情况下,则可以省略后面的那一对圆括号
    var o = new Object; // 有效,但不推荐省略圆括号
    仅仅创建Object的实例并没有什么用处,但这是所有它的实例的基础
    
  • Object的属性和方法

    • constructor:保存着用于创建当前对象的函数。
    • hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在,propertyName须以字符串形式指定,如"name"。
    • isPrototypeOf(object) :用于检查传入的对象是否是传入对象的原型。
    • propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句来枚举。
    • toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
    • toString():返回对象的字符串表示。
    • valueOf():返回对象的字符串、数值或布尔值表示。

3.4.8 数值转换

  • 非数值转换为数值

    • Number():可用于任何数据类型

      字符串
      var num1 = Number("Hello world!"); //NaN
      var num2 = Number(""); //0
      var num3 = Number("000011"); //11 
      var num4 = Number("0xf"); //十进制数15
      其它转换
      var num5 = Number(true); //1
      var num6 = Number(null); //0
      var num7 = Number(undefined); //NaN
      对象转换
      ——valueOf()——若结果为NaN——toString()
      
    • parseInt():仅能返回整数,丢失小数部分

      字符串
      var num1 = parseInt("1234blue"); // 1234
      var num2 = parseInt(""); // NaN
      var num3 = parseInt("Infinity"); // NaN
      var num4 = parseInt("12个人"); // 12(忽略字符)
      var num5 = parseInt("有12个人"); // NaN(头部非数字,识别出错)
      不同进制(为了避免错误解析,最好指定基数)
      var num6 = parseInt("0xAF", 16); //175
      var num7 = parseInt("AF", 16); //175
      var num8 = parseInt("AF"); //NaN
      var num9 = parseInt("10", 2); //2 (按二进制解析)
      var numA = parseInt("10", 8); //8 (按八进制解析)
      var numB = parseInt("10", 10); //10 (按十进制解析)
      var numC = parseInt("10", 16); //16 (按十六进制解析)
      省略小数
      var numD = parseInt(22.5); // 22
      var numE = parseInt(5.2e10); // 5(省略小数)
      
    • parseFloat():将字符串转为带小数的浮点数

      var num1 = parseFloat("12.23"); //12.23
      var num2 = parseFloat("12.23.34");//12.23(多余浮点无效)
      var num4 = parseFloat("12.23百分比");//12.23(忽略字符)
      var num4 = parseFloat("0xA"); //0
      var num5 = parseFloat("0908.5"); //908.5
      
  • 转换为字符串

    • toString()
      
      var age = 11;
      var ageAsString = age.toString(); // 字符串"11"
      var found = true;
      var foundAsString = found.toString(); // 字符串"true"
      
      进制转换(传递参数)
      var num = 10;
      alert(num.toString()); // "10"
      alert(num.toString(2)); // "1010"
      alert(num.toString(8)); // "12"
      alert(num.toString(10)); // "10"
      alert(num.toString(16)); // "a"
    
    • String():能够将任何类型的值转换为字符串
      var value1 = 10;
      var value2 = true;
      var value3 = null;
      var value4;
      alert(String(value1)); // "10"
      alert(String(value2)); // "true"
      alert(String(value3)); // "null"
      alert(String(value4)); // "undefined"
    

    由于 null 和 undefined 没有 toString() 方法,所以可以使用String()函数

3.5 操作符

3.5.1 一元操作符

  • 自加/递增(++)与自减/递减(--):放于前自加减后整体运算,放于后反之
  • 一元加(+)与减(-):相当于正负号

3.5.2 位操作符

  • 按位与(~
  • 按位与(&
  • 按位或(|
  • 按位异或(^
  • 左移(<<
  • 有符号右移(>>
  • 无符号右移(>>>

3.5.3 布尔操作符

  • 逻辑非(!):有非则反
  • 逻辑与(&&):两真才真
  • 逻辑或(||):有真就真

对于 A && B,当 A 被认定为 false,就不会再进行 B 的操作了

3.5.4 乘性操作符

  • 乘法(*
  • 除法(/
  • 求模取余(%

3.5.5 加性操作符

  • 加法(+
  • 减法(-

3.5.6 比较操作符

  • 关系操作符(> < >= <=
  • 相等( == )和不相等( !=
  • 全等(===)和不全等(!==

所有的比较操作符都会返回一个布尔值(true与false)

3.5.7 条件操作符

格式:【判断条件】?【满足输出】:【不满足输出】

var max = (num1 > num2) ? num1 : num2;

3.5.8 赋值操作符

由等于号(=)表示,其作用是把右侧的值赋给左侧的变量,复合赋值仅作简化操作。

var num = 10;
num = num + 10;
num += 10; // 等价于上一条语句

其它复合赋值运算符:加等+= 减等-= 乘等*= 除等/= 余等%= 左移等<<= 有符号右移等>>= 无符号右移等>>>=

复合赋值运算时,等号后面的部分是一个整体,如 y*=x-3 ——>y=y*(x-3)

3.5.9 逗号操作符

使用逗号(,)操作符可以在一条语句中执行多个操作。

var num1=1, num2=2, num3=3; // 声明多个变量
var num = (5,1,4,8,0); // num的值为0(多赋值时会返回表达式中的最后一项)

3.5.X 运算优先级

从高到低:算术操作符 → 比较操作符 → 逻辑操作符 → "="赋值符号

同级运算:按从左到右次序进行,多层括号由里向外

3.6 语句

3.6.1 if 语句

​ 条件判断语句,判断condition返回布尔值,若是true则执行statement1,若是false则执行statement2。

  • if (condition) statement1 else statement2

    if (i > 25)
    alert("Greater than 25."); // 单行语句
    else {
    alert("Less than or equal to 25."); // 代码块中的语句
    }
    
  • if (condition1) statement1 else if (condition2) statement2 else statement3

    if (i > 25) {
    alert("Greater than 25.");
    } else if (i < 0) {               // 多层条件判断
    alert("Less than 0.");
    } else {
    alert("Between 0 and 25, inclusive.");
    }
    

3.6.2 do-while 语句

​ 一种后测试循环语句,即先执行一次statement后,再判断expression,若返回false,则重新执行一次statement,直到返回true,才能往下继续执行。

do {statement} while (expression);

var i = 0;
do {
i += 2;
} while (i < 10);
alert(i);

3.6.3 while 语句

​ 一种前测试循环语句,即先判断expression,若返回true则执行一次statement,执行完后重新判断expression,若为false则跳过statement,再往下进行。

while (expression) statement

var count = 10;
var i = 0;
while (i < count){
alert(i);
i++;
}

3.6.4 for 语句

​ 另一种前测试循环语句,先执行initialization设定一个初始值,再判断expression,若返回true则去执行statement,执行完statement再去执行post-loop-expression,然后重新判断expression,直到返回false才跳出循环,往下执行。

for (initialization; expression; post-loop-expression) statement

var count = 10;
for (var i = 0; i < count; i++){
alert(i);
}   // 与前面while代码块执行的功能相同
  1. for循环是while循环的另一种表达,两者作用相同
  2. initialization可以不使用var关键字而在外部去定义
  3. 由于ECMAScript中不存在块级作用域,因此在循环内部定义的变量也可以在外部访问到
  4. for语句中的初始化表达式、控制表达式和循环后表达式都是可选(可省略)的

3.6.5 for-in 语句

​ 一种精准的迭代语句,用来枚举对象的属性。

for (property in expression) statement(变量 in 对象)

for (var propName in window) {
document.write(propName);
}

/* 
这里显示了 BOM 中 window 对象的所有属性。即每次执行循环时,都会将 window 对象中存在的一个属性名赋值给变量 propName 。这个过程会一直持续到对象中的所有属性都被枚举一遍为止。
*/

ECMAScript对象的属性没有顺序,因此不可预测的。所有属性都会被返回一次,但返回的先后次序可能会因浏览器而异。

3.6.6 label 语句

​ 在代码中添加标签,标签可以在将来由 break 或 continue 语句引用。一般都要与 for 语句等循环语句配合使用,从而返回代码中特定的位置。

label: statement

var num = 0;
outermost:
for (var i=0; i < 10; i++) {
    for (var j=0; j < 10; j++) {
        if (i == 5 && j == 5) {
            break outermost;
        }
        num++;
    }
}
alert(num);     //55
/* 退出内部循环(使用变量j循环),也退出外部循环(使用变量i循环)*/

var num = 0;
outermost:
for (var i=0; i < 10; i++) {
    for (var j=0; j < 10; j++) {
        if (i == 5 && j == 5) {
            continue outermost;
        }
        num++;
    }
}
alert(num);     //95
/* 强制继续执行循环——退出内部循环,执行外部循环 */

3.6.7 break 和 continue 语句

​ 用于在循环中精确地控制代码的执行。

break:立即跳出循环,强制继续执行循环后面的语句

continue :结束本次循环后会从循环的顶部重新执行

var num = 0;
for (var i=1; i < 10; i++) {
    if (i % 5 == 0) {
    break;
    }
num++;
}
alert(num);     //4

var num = 0;
for (var i=1; i < 10; i++) {
    if (i % 5 == 0) {
    continue;
    }
num++;
}
alert(num);     //8

3.6.8 with 语句

​ 将代码的作用域设置到一个特定的对象中,目的主要是为了简化多次编写同一个对象的工作。

with (expression) statement;

原程序(包含了多个location对象)
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;

改为
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}

大量使用 with 语句会导致性能下降,同时也会给调试代码造成困难,因此
在开发大型应用程序时,不建议使用 with 语句。

3.6.9 switch 语句

​ 另一种条件判断分支语句,设置一个变量 i,让其值与结构中的每个情况 case 值做比较,若存在匹配,则执行该 case 关联的代码块,执行完后使用 break 来跳出此 case同时阻止继续运行下一个 case,若无对应值时直接执行 default 关联的代码块。

switch (expression) {case A: statet1 break; case B: state2 break; default: state3}

switch (i) {
    case 25:
        alert("25");
        break;
    case 35:
        alert("35");
        break;
    case 45:
        alert("45");
        break;
    default:
        alert("Other");
}

  1. expression可以使用任何数据类型,无论是字符串或是对象
  2. 每个 case 的值不一定是常量,可以是变量,甚至是表达式

3.7 函数

​ 函数可以封装任意多条语句,在任何地方在、任何时候需要调用时执行。函数在定义时不必指定是否返回值,但可通过 return 语句来实现值的返回。

function functionName (arg0, arg1, ...) {statements}

function sayHi(name, message) {
alert("Hello " + name + "," + message);
}
sayHi("Nicholas", "how are you today?");

/* 这个函数的输出结果是 "Hello Nicholas,how are you today?" */

function sum (num1, num2) {return num1 + num2;}

var result = sum(5, 10);
function sum(num1, num2) {
    return num1 + num2; // 执行完return语句之后停止并立即退出
    alert("Hello world"); // 永远不会执行
}

return语句也可以不带有任何返回值(return;),函数在停止执行后将返回 undefined值,但推荐做法是要么让函数始终都返回一个值,要么永远都不要返回值

3.7.1 理解参数

​ 命名的参数只提供便利,但不是必需的。

3.7.2 没有重载

​ 其他语言中可以为一个函数编写两个定义,只要这两个定义的签名不同即可。由于不存在函数签名的特性,ECMAScript 函数不能重载。如果在 ECMAScript 中定义了两个名字相同的函数,则该名字只属于后定义的函数。

function addSomeNumber(num){
return num + 100;
}
function addSomeNumber(num) {
return num + 200;
}
var result = addSomeNumber(100); //300

/* 
addSomeNumber()被定义了两次,由于后定义的函数覆盖了先定义的函数,程序只执行最后定义的函数
*/

3.7.3 常用函数

  • document.getElementById(id).innerHTML:访问某个 HTML 元素,并获取对象的内容或向对象插入内容
  • document.write():向文档输出写内容,执行后整个 HTML 页面将被覆盖

第 4 章 变量、作用域和内存

4.1 基本类型和引用类型

  • 数据类型的值
    • 基本类型值:简单的数据段
    • 引用类型值:由多个值构成的对象

JavaScript不能直接操作对象的内存空间,而是在操作对象的引用

4.1.1 动态的属性

基本类型值——添加属性会无效
var name = "Nicholas";
name.age = 27;
alert(name.age); //undefined

引用类型值——可以操作属性与方法
var person = new Object();
person.name = "Nicholas";
alert(person.name); //"Nicholas"

4.1.2 复制变量值

​ 复制基本类型的值,原变量与副本变量可以参与任何操作而不会相互影响

var num1 = 5;
var num2 = num1;

​ 复制引用类型的值,副本变量是一个指针(并非自身),原变量与副本都将引用同一个对象,其一改变都会影响另一变量

var obj1 = new Object();
var obj2 = obj1;
obj1.name = "Nicholas";
alert(obj2.name); //"Nicholas"

4.1.3 传递参数

​ ECMAScript 中所有函数的参数都是按值传递的,即与复制变量值一样

4.1.4 检测类型

  • typeof:检测基本类型值(字符串、数值、布尔值、undefined)

用来检测对象或 null 会返回 "object",某些浏览器检测函数会返回 "function"

  • instanceof:检测引用类型值
  • 语法:``变量名instanceof类型(Object/Array/RegExp)`
  • 返回值:true 与 false(若用来检测基本类型值始终返回 false)

4.2 执行环境及作用域

  • 执行环境的类型只有两种——全局环境和局部/函数环境
  • 每次进入一个新执行环境,都会创建一个用于搜索变量和函数的作用域链
  • 函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含父环境,乃至全局环境
  • 全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据
  • 变量的执行环境有助于确定应该何时释放内存
var color = "blue";
function changeColor(){
    var anotherColor = "red";
    function swapColors(){
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
        // 这里可以访问 color、anotherColor 和 tempColor
}
    // 这里可以访问 color 和 anotherColor,但不能访问 tempColor
    swapColors();
}
// 这里只能访问 color
changeColor();

graph LR
A[window]   -->B(color)
A           -->C(changeColor)
    C -->D(anotherColor)
    C -->E(swapColor)
         E -->F(tempColor)

4.2.1 延长作用域链

  • try-catch 语句的 catch 块
  • with 语句

4.2.2 没有块级作用域

  • 声明变量

    function add(num1, num2) {
      var sum = num1 + num2;  // 使用var,变量会自动被添加局部环境
      return sum;
    }
    var result = add(10, 20); //30
    alert(sum); //由于 sum 不是有效的变量,因此会导致错误
    
    
    function add(num1, num2) {
      sum = num1 + num2;  // 没有使用var,变量会自动被添加到全局环境
      return sum;
    }
    var result = add(10, 20); //30
    alert(sum); //30,且变量sum会永久存在
    
    
  • 查询标识符

    var color = "blue";
    function getColor(){
      return color;
    }
    alert(getColor()); //"blue"
    
    
    var color = "blue";
    function getColor(){
      var color = "red";  // 在函数内新增了局部变量
      return color;
    }
    alert(getColor()); //"red",搜索会从局部开始,找到后返回此值并停止搜索
    
    

4.3 垃圾收集

  • JavaScript 具有自动垃圾收集机制,会自动释放无用的内存占用
  • 两种垃圾收集方式
    • 标记清除:在变量进/出环境时跟踪标记
    • 引用计数:跟踪记录每个值被引用的次数 不推荐
  • 性能问题:为避免垃圾内存占用过大而确定垃圾收集的时间间隔的问题
  • 管理内存:为尽量减少Web浏览器内存,可通过将其值设置为 null 来释放其引用

第 5 章 引用类型

5.1 Object 类型

  • 创建方法

    使用new + Object()定义
    var person = new Object();
    person.name = "Nicholas";
    person.age = 29;
    
    简化new定义
    var person = {};
    person.name = "Nicholas";
    person.age = 29;
    
    对象字面量表示法
    var person = {
    name : "Nicholas",
    age : 29          // 最后一个属性后不能加逗号(,)
    };
    
    
  • 访问方法

    alert(person.name);  // 点表示法——更简洁(推荐)
    alert(person["name"]); // 方括号表示法——更方便,可直接通过变量名访问
    
    

5.2 Array 类型

  • 创建方法

    使用Array构造函数
    var colors = new Array();
    
    使用length长度构造
    var colors = new Array(20);
    
    直接赋值构造
    var colors = new Array("red", "blue", "green");
    
    省略new操作符构造
    var colors = Array(3); 
    
    使用数组字面量表示法
    var colors = ["red","blue","green"]; //创建一个包含3个字符串的数组
    var names = []; // 创建一个空数组
    var values = [1,2,]; // 不要这样!这样会创建一个包含2或3项的数组
    var options = [,,,,,]; // 不要这样!这样会创建一个包含5或6项的数组
    
    
  • 访问方法

    /* 定义一个字符串数组,方括号中的数字索引表示要访问的值 */
    var colors = ["red", "blue", "green"]; // 序号为0、1、2…
    
    alert(colors[0]); // 显示第一项
    colors[2] = "black"; // 修改替换第三项
    colors[3] = "brown"; // 新增第四项(索引超过项数)
    
    /* 数组的项数保存在其length属性中 */
    alert(colors.length); // 3
    alert(names.length); // 0
    
    /* 使用length可从数组末尾移除项或向数组中添加新项 */
    colors.length = 2; //将color数组的length属性设置为2,移除最后一项
    colors.length = 4; //将其length属性设置为大于数组项数的值,新增一项
    alert(colors[2]); // undefined
    alert(colors[3]); // undefined
    
    /* 利用length属性也可以在数组末尾直接添加新项 */
    colors[colors.length] = "black"; // (在位置3)添加一种颜色
    colors[colors.length] = "brown"; // (在位置4)添加一种颜色
    
    /* 在指定位置出直接插入添加 */
    colors[99] = "black"; // (在位置99)添加一种颜色
    alert(colors.length); // 100 (数组长度也会随之改变)
    
    

5.2.1 检测数组

if (value instanceof Array){}   // 旧方法,可能分别具有各自不同的构造函数
if (Array.isArray(value)){}     // 新方法,能最终确定某个值到底是不是数组

5.2.2 转换方法

除 toLocaleString() 、toString()、valueOf()方法,还有join()方法转换字符串。

var colors = ["red", "green", "blue"];
alert(colors.join(",")); // red,green,blue
alert(colors.join("||")); // red||green||blue

5.2.3 栈方法

​ 类似栈“后进先出”,push()方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。而pop()方法则从数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。

var colors = new Array(); // 创建一个数组

var count = colors.push("red", "green"); // 推入两项
alert(count); //2
count = colors.push("black"); // 推入另一项
alert(count); //3

var item = colors.pop(); // 取得最后一项
alert(item); //"black" (最后一项被移出,放于item中)
alert(colors.length); //2 

5.2.4 队列方法

​ 类似队列的“先进先出”,shift()方法能够移除数组中的第一个项并返回该项,同时将数组长度减 1,与push()方法结合共同完成。

var colors = new Array(); //创建一个数组

var count = colors.push("red", "green"); //推入两项
alert(count); //2
count = colors.push("black"); //推入另一项
alert(count); //3

var item = colors.shift(); // 取得第一项
alert(item); //"red"
alert(colors.length); //2

​ 使用unshift()方法能在数组前端添加任意个项并返回新数组的长度。与pop() 方法结合可以从相反的方向来模拟队列,即在数组的前端添加项,从数组末端移除项。

var count = colors.unshift("red", "green"); // 推入两项
alert(count); //2
count = colors.unshift("black"); // 推入另一项
alert(count); //3

var item = colors.pop(); // 取得最后一项
alert(item); //"green"
alert(colors.length); //2

5.2.5 重排序方法

reverse()方法可以反转数组项的顺序
var values = [1, 2, 3, 4, 5];
values.reverse();
alert(values);  //5,4,3,2,1

sort()方法可以调用toString()方法转型为字符串,再按升序排列数组项
var values = [0, 1, 5, 10, 15];
values.sort();
alert(values);  //0,1,10,15,5(会打乱排序,可定义一个比较函数与之结合实现)

5.2.6 操作方法

concat()方法可以基于当前数组中的所有项创建一个新数组,若没有传参数,它只是复制当前数组并返回副本。

var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);
alert(colors); //red,green,blue
alert(colors2); //red,green,blue,yellow,black,brown

slice()方法能够基于当前数组中的一或多个项创建一个新数组,且不会影响原始数组。

var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1);  //只有一个参数
var colors3 = colors.slice(1,4);    //有两个参数
alert(colors2); //green,blue,yellow,purple(返回该项至末项的所有项)
alert(colors3); //green,blue,yellow(返回两参数对应项间且不含末项的所有项)

splice()方法用于对数组进行删除、插入与替换操作

var colors = ["red", "green", "blue"];

/* 删除:指定2个参数,分别代表起始位置、删除项数 */
var removed = colors.splice(0,1); 
alert(colors); // green,blue
alert(removed); // red(返回删除项)

/* 插入:指定3个参数,分别代表起始位置、0、要插入的项 */
removed = colors.splice(1, 0, "yellow", "orange");
alert(colors); // green,yellow,orange,blue
alert(removed); // 返回空数组

/* 替换:指定3个参数,分别代表起始位置、删除项数、要插入的项 */
removed = colors.splice(1, 1, "red", "purple"); // 插入两项,删除一项
alert(colors); // green,red,purple,orange,blue
alert(removed); // yellow

5.2.7 位置方法

indexOf()方法从头到尾顺向查找,lastIndexOf() 方法则从尾向前逆向查找,两个方法会接收两个参数——要查找的项、查找起点索引(可选),要求全等===查找。

var numbers = [1,2,3,4,5,4,3,2,1];

alert(numbers.indexOf(4)); //3 顺序查找值4,返回索引值3
alert(numbers.lastIndexOf(4)); //5 逆序查找值4,返回索引值5
alert(numbers.indexOf(4, 4)); //5 指定了索引为5的值开始顺序查找值4
alert(numbers.lastIndexOf(4, 4)); //3

var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];
var morePeople = [person];
alert(people.indexOf(person)); //-1 (没找到的情况下返回-1)
alert(morePeople.indexOf(person)); //0

5.2.8 迭代方法

  • 对数组中的每一项运行给定函数(接收3个参数——数组项的值、该项的位置、数组对象本身),使用以下迭代方法
    • every():如果该函数对每一项都返回true,则最终结果返回true
    • some():如果该函数对任一项都返回true,则最终结果返回true
    • filter():返回该函数会返回true的项组成的数组
    • map():返回每次调用的结果组成的数组
    • forEach:此方法没有返回值
var a = [1, 2];

a.every(function(item, index, array){
    return (item >1);
})          // 输出结果:false
a.some(function(item) {
    return (item >1);
})          //输出结果:true
a.filter(function(item) { 
    return (item >1);
})          //输出结果:[2]
a.map(function(item) { 
    return item ;
})          //输出结果:[1,2]
a.forEach(item) {
    console.log(item);
}           //输出结果:1 2

5.2.9 归并方法

  • 使用以下两个方法,接收2个参数——调用函数、归并初始值(可选),都会迭代数组的所有项,然后构建一个最终返回的值
    • reduce():顺序遍历
    • reduceRight():逆序遍历
var values = [1,2,3,4,5];

var sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15

var sum1 = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
});
alert(sum1); //15

5.3 Date 类型

/* 创建当前代码的执行时间(定格) */
var now = new Date();
/* 创建指定时间(设置日期时间格式) */
var date = new Date("May 25, 2004"); 

5.3.1 继承的方法

​ 由于Date类型重写了toLocaleString()、toString()和valueOf()方法,它们最终在不同浏览器上显示的格式会有所不同。

5.3.2 日期格式化方法

  • toDateString() ——以特定于实现的格式显示星期几、月、日和年
  • toTimeString() ——以特定于实现的格式显示时、分、秒和时区
  • toLocaleDateString() ——以特定于地区的格式显示星期几、月、日和年
  • toLocaleTimeString() ——以特定于实现的格式显示时、分、秒
  • toUTCString() ——以特定于实现的格式完整的 UTC 日期

5.3.3 日期/时间组件方法

JavaScript 知识点总结_第1张图片
image

注意:大部分的返回值里,0代表现实意义中的1(如1号、1月份、1秒)

5.4 RegExp 类型

创建正则表达式:var expression = / pattern / flags ;

5.4.1 RegExp 实例属性

5.4.2 RegExp 实例方法

5.4.3 RegExp 构造函数属性

5.4.4 模式的局限性

5.5 Function 类型

5.5.1 没有重载(深入理解)

5.5.2 函数声明与函数表达式

5.5.3 作为值的函数

5.5.4 函数内部属性

5.5.5 函数属性和方法

5.6 基本包装类型

5.6.1 Boolean 类型

5.6.2 Number 类型

5.6.3 String 类型

5.7 单体内置对象

5.7.1 Global 对象

5.7.2 Math 对象

你可能感兴趣的:(JavaScript 知识点总结)