JavaScript学习笔记

  大二开始接触前端,当时慕名买了本《JavaScript高级程序设计》看的一脸懵逼,一直没看进去,后来忙毕业设计,忙着工作,一直没时间再去仔细翻看这本书。工作后才知道前端的博大精深,各种框架眼花缭乱,还没用明白能就又更新了,深刻体会到还是要打好基础才能融会贯通。最近不太忙,又捡起了这本书,有了三年多工作中挖坑填坑的经验,才真正体会到这本书的厉害。我把书中对我有用的地方都摘出来了做下笔记。方便以后快速复习。毕竟抱一本这么厚的书啃还是很费劲的。希望对你也有用吧。

1. JavaScript简介

1.1JavaScript 实现

  一个完整的JavaScript应该由下列三部分组成:

  • 核心(ECMAScript):由ECMA-262定义,提供核心语言功能
  • 文档对象模型(DOM):提供访问和操作页面内容的方法和接口
  • 浏览器对象模型(BOM):提供与浏览器交互的方法和接口

1.2 DOM级别

  • DOM1级:由两个模块组成:DOM核心(DOM Core)和DOM HTML。其中,DOM核心规定的是如何映射基于XML的文档结构,以便简化对文档中任意部分的访问和操作。DOM HTML模块则再DOM核心的基础上加以扩展,添加了针对HTML的对象和方法。DOM1级的目标主要是映射文档的结构。
  • DOM2级:在原来DOM的基础上又扩充了鼠标和用户界面时间、范围、遍历(迭代DOM文档的方法)等细分模块,而且通过对象接口添加了对CSS的支持
  • DOM3级:引入了以统一方式加载和保存文档的方法——在DOM加载和保存模块中定义;新增了验证文档的方式——在DOM验证模块中定义。DOM3级也对DOM核心进行了推广,开始支持XML 1.0规范,涉及XML Infoset、Xpath和XML Base。

2. 在HTML中使用JavaScript

2.1 文档模型

  • 混杂模型
  • 标准模型

2.2 <noscript>元素

  使用<noscript>元素可以指定在不支持脚本的浏览器中显示的替代内容。但在启动了脚本的情况下,浏览器不会显示<noscript>元素中的任何内容。

3 基本概念

3.1 语法

  标识符:就是指变量、函数、属性的名字,或者函数的参数。标识符可以是按照下列格式规则组合起来的一个或多个字符:

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

3.2 数据类型

  ECMAScript中有5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和String。还有1种复杂数据类型——Object

3.3 语句

3.3.1 label语句

  使用label语句可以在代码中添加标签,以便将来使用。以下是label语句的语法:

label: statement

  下面是一个示例:

start: for(var i = 0; i < count; i++) {
  alert(i);  
}

  这个例子中定义的start标签可以在将来由break或continue语句引用。加标签的语句一般都要与for语句等循环语句配合使用。

3.3.2 with语句

  with语句的作用是将代码的作用域设置到一个特定的对象中。with语句的语法如下:

with (expression) statement;

  定义with语句的目的主要是为了简化多次编写同一个对象的工作,如下面的例子所示:

var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;

  上面几行代码都包含location对象。如果使用with语句,可以把上面的代码改写成如下所示:

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

3.4 函数

  ECMAScript函数的参数与大多数其他语言中函数的参数有所不同。ECMAScript函数不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型。在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的被一个参数。

  ECMAScript函数不能像传统意义上那样实现重载,如果在ECMAScript中定义了两个名字相同的函数,则该名字只属于后定义的函数。

 

4. 变量、作用域和内存问题

4.1 基本数据类型和引用数据类型

  基本数据类型指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象。

4.2 执行环境及作用域

  执行环境是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。

  当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。

  JavaScript没有块级作用域

4.3 垃圾收集

  JavaScript具有自动垃圾收集机制。这种垃圾收集机制的原理很简单:找出那些不再继续使用的变量,然后释放其占用的内存。为此,垃圾收集器会按照固定的时间间隔(或代码执行中预定的收集时间),周期性地执行这一操作。

  • 标记清除:是目前主流得到垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存。
  • 引用计数:这种算法的思想是跟踪记录所有值被引用的次数。JavaScript引擎目前都不再使用这种算法;但在IE中访问非原生JavaScript对象(如DOM元素)时,这种算法仍然可能会导致问题。

5. 引用类型

5.1 Object类型

5.2 Array类型

5.2.1 监测数组

if(value instanceof Array) {
    //对数组执行某些操作
}

if(Array.isArray(value)) {
    //对数组执行某些操作
}

5.2.2 转换方法

  toString() 、valueOf()、toLocaleString()、join()

5.2.3 栈方法

  push()、pop()

5.2.4 队列方法

  结合使用shift()和push()方法,可以像使用队列一样使用数组,在列表末端添加项,从前端移除项。

  同时使用unshift()和pop()方法,可以从相反的方向来模拟队列。

5.2.5 重排序方法

  reverse()降序、sort()升序

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"];
var removed = colors.splice(0, 1);                         //删除第一项
alert(colors); // green, blue
alert(removed); // red, 返回的数组中只包含一项

removed = colors.splice(1, 0, "yellow", "orange");        //从位置1开始插入两项
alert(colors); // green, yellow, orange, blue
alert(removed); // 返回的是一个空数组

removed = colors.splice(1, 1, "red", "purple");            //插入两项,删除一项
alert(colors);  // green, red, purple, orange, blue
alert(removed);  // yellow, 返回的数组中只包含一项

5.2.7 位置方法

  • indexOf() :从数组的开头开始向后查找
  • lastIndexOf() :从数组的末尾开始向前查找

5.2.8 迭代方法 

  • every() : 对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true
  • filter() : 对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。
  • forEach() : 对数组中的每一项运行给定函数,这个方法没有返回值。
  • map() : 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
  • some() : 对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。

5.2.9 缩小方法

  reduce() 和 reduceRight() 这两个方法都会迭代数组的所有相,然后构建一个最终返回的值。器重reduce() 方法从数组的第一项开始,逐个遍历到最后。而 reduceRight() 则从数组的最后一项开始,向前遍历到第一项。

5.3 Date类型

5.4 RegExp类型

5.5 Function 类型

5.5.1 函数是对象,函数名是指针

5.5.2 没有重载

5.5.3 函数内部属性

  • arguments: 它是一个类数组对象,包含着传入函数中的所有参数,这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数
  • this: this引用的是函数据以执行的环境对象
  • caller:这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用单签函数,它的值为null。

5.5.4 函数属性和方法

  • length:表示函数希望接受的命名参数的个数
  • prototype:对于ECMAScript中的引用类型而言,prototype是保存它们所有实例方法的真正所在
  • apply()和call():这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。call()方法:第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。它们真正强大的地方是能够扩充函数赖以运行的作用域。
  • bind(): 这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值

5.6 基本包装类型

  为了便于操作基本类型值,ECMAScript还提供了3个特殊的引用类型:Boolean、Number和String。

  引用类型与基本包装类型的主要区别就是对象的生存期。使用new操作符创建的引用类型的实例,在执行流离开当前作用域之后一直存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。

5.6.1 String类型

  • 字符方法: charAt()和charCodeAt
  • 字符串操作方法: concat();slice()、substr()和substring()
  • 字符串位置方法:indexOf() lastIndexOf()
  • trim() 方法: 这个方法会创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果。
  • 字符串大小写转换方法:toLowerCase()、toLocaleLowerCase()、toUpperCase()和toLocaleUpperCase()
  • 字符串的模式匹配方法:match()、search()、replace()、split()
  • localeCompare()方法:这个方法比较两个字符串
  • fromCharCode()方法:这个方法的任务是接收一或多个字符编码,然后将它们转换成一个字符串。

5.7 单体内置对象

  由ECMAScript实现提供的,不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了。

5.7.1 Global对象

  ECMAScript中的Global对象在某种意义上是作为一个终极的“兜底儿对象”来定于的。换句话说,不属于热河其他对象的属性和方法,最终都是它的属性和方法。

  eval():它会将传入的参数当做实际的ECMAScript语句来解析,然后把执行结果插入到原位置。

5.7.2 Math对象

6 面向对象的程序设计

6.1 理解对象:

  ESMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数”

6.1.1 属性类型

  ECMAScript中有两种属性:数据属性和访问器属性。

  1. 数据属性

  数据属性包含一个数据值得为之。在这个为之可以读取和写入值。数据属性有4个描述其行为的特性。

  • [[configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。
  • [[enumerable]]:表示能否通过for-in循环返回属性。
  • [[writable]]:表示能否修改属性的值。
  • [[value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。这个特性的默认值为undefined。

  要修改属性默认的特性,必须使用ECMAScript5的Object.defineProperty()方法。这个方法接收单个参数:属性所在对象、属性的名字和一个描述符对象。其中,描述符对象的属性必须是configurable、enumerable、writable和value。

var person = {};
Object.defineProperty(person, "name", {
    writable: false,
    value: "Nicholas"
});

alert(person.name);    // "Nicholas"
person.name = "Greg";
alert(person.name);    // "Nicholas"

  2. 访问器属性

  访问器属性不包含数据值;它们包含一对getter和setter函数,在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据。

var book = {
    _year: 2004,
    edition: 1  
};

Object.defineProperty(book, "year", {
    get: function() {
        return this._year;    
    },
    set: function() {
        if(newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});

book.year = 2005;
alert(book.edition);    //2

6.1.2 定义多个属性

  由于未对象定义多个属性的可能性很大,ECMAScript5又定义了一个Object.defineProperties()方法。利用这个方法可以通过描述符一次定义多个属性

var book = {};

Object.definePropertied(book, {
    _year: {
        value: 2004
    }, 

    edition: {
        value: 1
    },

    year: {
        get: function() {
            return this._year;
        },
        
        set: function(newValue) {
            if(newValue > 2004) {
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    },

});

6.1.3 读取属性的特性

  使用ECMAScript5的Object.getOwnPerpertyDecriptor()方法,可以取得给定属性的描述符。这个方法接收两个参数:属性所在的对象和要读取其描述符的属性名称

 

posted @ 2020-07-21 18:08  进击的丹子  阅读(171)  评论(0)    收藏  举报