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()方法,可以取得给定属性的描述符。这个方法接收两个参数:属性所在的对象和要读取其描述符的属性名称

浙公网安备 33010602011771号