第四章
两种不同数据类型的值: 基本类型值, 引用类型值
基本类型值: Undefined, Null, Boolean, Number, String
基本类型值在内存中占据固定大小的空间, 因此保存在栈内存中
引用类型的值是对象, 保存在堆内存中
- 动态的属性:
定义和创建接不类型值和引用类型值的方式类似: 创建一个变量并为该变量赋值
只能给引用类型值动态的添加属性方法,以便将来使用 - 复制变量值
- 从一个变量向两一个变量复制基本类型值:相当于创建了一个新的值并且赋值给变量对象, 创建值的一个副本
- 引用类型值的赋值: 是复制了一个指针,把指针的值赋给新的变量对象
- 传递参数
ECMAScript中所有函数的参数都是值传递的 - 检测类型
基本类型值的检测: typeof() 检测对象是否是字符串(string),数值(number), 布尔值(boolean), 还是undefined,对于引用类型统一返回object
引用类型值的检测: instanceof 语法: result = variable instanceof constructor, 在检测一个引用类型值变量跟Object构造函数时始终返回true,基本类型返回false
执行环境及作用域
执行环境
执行环境(环境)定义了变量或函数有权访问的其他数据,决定了他们的各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的变量和函数都保存在这个对象中。决定了变量的生命周期
- 全局执行环境: 全局执行环境是最外层的执行环境
- 函数执行环境: 每个函数都有自己的执行环境,环境栈
作用域链
当代码在一个环境中执行时,会创建变量对象的一个作用域链。环境是函数时, 活动对象(arguments)作为变量对象
内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境的任何变量和函数。
作用域链延长:1. try-catch语句的catch, 2. with语句
没有块级作用域
- 声明变量: 使用var声明的变量会自动添加到最接近的环境,如果在函数中,最近的环境就是函数的局部环境。如果没有用var 声明,该变量会自动添加到全局环境(严格模式行不允许这样)。
- 查询标识符: 搜索从作用域前端开始, 向上逐级查询与给定标识符匹配的字符串。同名标识符局部环境的会瓶坯父环境中的标识符
垃圾回收
- 标记清楚
- 引用计数
- 性能问题
- 管理内存 解除引用: 将一个对象值设置为null,作用是让其脱离执行环境,以便垃圾收集器下次将他回收。
第五章 引用类型
引用类型值(对象)是引用类型的一个实例: 对象是某个特定引用类型的实例, 新对象使用new操作符后跟一个构造函数来创建的。构造函数本身就是一个函数,只是出于创建新对象的目的定义的。
Object类型
- 两种创建方式:
new 操作符后跟Object构造函数
123var person = new Object();person.name = "nico";person.age = 29;对象字面量表示法:
1234var person = {name: "nico",age: 29};
- 对象属性的访问:
- 点表示法,如:person.age;
- 方括号表示法: 如: person[“name”];
Array
- 两种创建方式:
new 加Array构造函数
123var colors = new Array();var colors1 = new Array(3); // 创建一个包含三项的数组var name = new Array("Grey"); // 创建一个包含一项的数组数组字面量法:
123var colors = ["red", "blue"];var names = []; // 空数组var values = [1, 2,]; // 不要这样这样会创建一个2项或者三项的数组
数组读取: 读取和设置数组的值时, 使用方括号和基于0的数字索引: colors[1] = “black”;
数组的length, 不止可读,也可以进行设置检测数组
- value instanceof Array 有局限性: 只能用于单一的全局执行环境
- Array.isArray(value) (ECMAScript5 新增)
转换方法
每个对象都有toLocaleString(), toString(), valueOf()方法
数组继承的这三个方法,在默认情况下都会以逗号分隔的字符串形式返回数组项
join()方法可以使用不同的分隔符来构建这个字符串 colors.join(“||”);
如果数组的某一项值时null或者undefined,那么在返回的结果中以空字符串表示栈方法
栈是一种LIFO(Last-In-First-Out)后进先出的数据结构,栈的插入(推入)和移除(弹出)只发生在栈顶
ECMAScript为数组提供了push(), pop()来实现栈方法队列方法
队列数据结构访问规则:FIFO(First-In-First-Out)先进先出,队列在队尾添加项, 在队头移除项
通过push(), shift()来实现队列方法
通过unshift(), pop()来反向模拟队列重排序方法
reverse()反转数组项的顺序
sort()给数组排序,默认按升序排序数组, 默认是比较字符串,将数组每一项都转化成字符串然后比较
sort()可以接受一个比较函数,比较函数接受两个参数,如果第一个参数应该在第二个参数之前就返回一个负数,相等返回0,第一个参数应该位于第二个参数之后返回1。操作方法
concat() 拼接数组,原数组不变,生成一个拼接后的数组
slice() 基于当前数组的一项或者多项创建一个数组,相当于截取数组,接受两个参数:返回项的起始位置和结束位置,第二个参数省略的话就是默认数组结尾,有参数的话不包含结束位置的这一项
splice() 最强的数组操作方法,可用于:
- 删除: 两个参数,要删除的第一项的位置和删除的项数
- 插入: 三个参数,起始位置,0(表示不删除), 要插入的项
- 替换: 三个参数,起始位置, 要删除的项数, 插入的项
位置方法
indexOf(): 从数组的开头向后查找
lastIndexOf(): 从数组的末尾向前查找
上边两个方法有两个参数: 要查找的项,(可选的)表示查找起点位置的索引迭代方法
ECMAScript5为数组定义了5个迭代方法,每个方法接受两个参数: 要在每一项上运行的函数, (可选的)运行该函数的作用域对象
而这个作为参数的函数一般有三个参数,数组项的值,该项在数组的位置和数组对象本身
- every(): 对数组中每一项运行给定函数,如果该函数对每一项都返回true,则返回true
- filter(): 对数组中每一项运行给定函数,返回该函数能够返回true的项构成的数组
- forEach(): 对数组中每一项运行给定函数, 没有返回值
- map(): 对数组中每一项运行给定函数, 返回每次函数调用结果组成的数组
- some(): 对数组中每一项运行给定函数, 如果有一项该函数返回true就返回true12345var numbers = [1, 2, 3, 4];var result = numbers.map(function(item, index, array){return item * 2;});alert(result); // [2, 4, 6, 8]
- 缩小方法
reduce()和reduceRight()这两个方法都会迭代数组所有项,然后构建一个最终返回的值。
reduce()是从数组第一项开始遍历到最后
reduceRight()是从数组最后一项开始遍历到第一项
都接受两个参数: 在每一项上调用的函数, (可选的)作为缩小基础的初始值
传入的第一个参数的函数接受四个参数: 前一个值,当前值,想的索引和数组对象。这个函数返回的任何值会作为第一个参数自动传给下一项。
第一次迭代是发生在数组的第二项上,因此第一个参数是数组第一项,第二个参数是数组第二项 如:123456789var values = [1, 2, 3, 4];var sum = values.reduce(function(prev, cur, index, array){return prev + cur;}); // ((1+2) + 3) + 4var sum2 = values.reduceRight(function(prev, cur, index, array){return prev + cur;}); // ((4+3) + 2) + 1alert(sum); // 10alert(sum1); // 10
方法 | 作用 | 返回值 |
---|---|---|
push() | 在数组末尾添加项 | 修改后的数组长度 |
pop() | 从数组末尾移除最后一项 | 移除的项 |
shift() | 移除数组中的第一项 | 移除的项 |
unshift() | 在数组前端添加项 | 修改后的数组长度 |
reverse() | 反转数组项的顺序 | 反序后的数组 |
sort() | 数组排序 | 排序后的数组 |
concat() | 数组拼接 | 拼接后的数组 |
slice() | 数组截取 | 截取后的数组 |
splice() | 数组插入,删除,替换 | 操作后的数组 |
indexOf() | 从前往后查找位置 | 项所在的索引 |
lastIndexOf() | 从后往前查找位置 | 项所在的索引 |
Date类型
创建日期对象: var now = new Date(); 没有参数时,新创建的对象自动获得当前时间
如果根据日期和时间来创建日期对象,必须传入该日期的毫秒数,不方便
为了简化提供了一个方法: Date.parse()将日期转化为毫秒数; 其实Date()在后台自动调用Date.parse();
Date.UTC()方法也同样返回表示日期的毫秒数,Date.UTC()的参数分别是年数, 基于0的月份, 月中的某一天, 小时数(0-23), 分钟, 秒以及毫秒
如:
Date.now()方法返回表示调用这个方法时的日期和时间的毫秒数
RegExp 类型
var exp = / pattrn / flags;
flags
- g 表示全局匹配
- i 表示忽略大小写
- m 表示多行匹配
| 表示 | 含义 |
| :—– | :—– |
| \d | 匹配一个数字 |
| \w | 匹配一个字符或者数字 |
| . | 匹配任意一个字符 |
| * | 任意个字符(包括0个) |
| + | 表示至少一个字符 |
| ? | 表示0个或者一个字符 |
| {n} | 表示n个字符 |
| {n,m} | 表示n-m个字符 |
| \s | 匹配一个空格(包括Tab等空格符) |
| A|B | 表示n-m个字符 |
| ^ | 表示行的开头(^\d 表示以数字开头) |
| $ | 表示行的结束(\d$ 表示以数字结尾) |
| [] | 表示范围 [0-9a-zA-Z_]可以匹配一个数字字符或者下划线 |
Function 类型
- 两种定义方式
函数声明语法定义:
123function sum (num1, num2) {return num1 + num2;}函数表达式定义:
123var sun = function (num1, num2) {return num1 + num2;};
区别:解析器会执行一个函数声明提升的过程(function declaration hoisting)
没有函数重载
函数内部属性
arguments: 包含传入函数的参数
arguments对象有一个callee的属性,改属性是一个指针指向拥有这个arguments的函数(在严格模式下会出错)
一个阶乘函数:12345678910111213141516171819202122232425262728293031323334function factorial(num) {if(num <= 1) {return 1;} else {return num * factorial(num - 1);}} // 缺点: 函数的执行和函数名factorial紧紧耦合在一起---function factorial(num) {if(num <= 1) {return 1;} else {return num * arguments.callee(num - 1);}} // 缺点: 严格模式下arguments.callee会出错---function factorial() {return (function f(num){if (num <= 1) {return 1;} else {return num * f(num -1)}});} // 缺点: 调用方法比较繁琐:factorial()(num);console.log(factorial()(5));---var factorial = (function f(num) {if (num <= 1) {return 1;} else {return num * f(num -1)}}); // 完美this: 引用的是函数数据执行的环境对象
- 函数对象的另一个属性caller: 保存着调用当前函数的函数的引用
- 函数方法和属性
- 函数是对象,因此函数也有属性和方法, 每个函数都包含的属性:
- length: 表示函数希望接受的命名参数的个数
- prototype: 保存引用类型所有的实例方法的真正所在(prototype属性不可枚举)
- 每个函数都有两个非继承而来的方法:
这两个方法都是在特定的作用域下运行函数,实际上就是设置函数内this的值,都接收两个参数
- apply(): 参数:函数在其中运行的作用域, 另一个是参数数组(可以是Array的实例,也可以是arguments对象)
- call(): 参数:函数在其中运行的作用域, 另一个是参数(将参数逐个罗列出来)
ECMAScript还定义了一个bind()方法 这个方法会创建一个函数的实例,其this值会被绑定传给bind()函数的值
基本包装类型
基本包装类型是Number, Boolean, String;尽量不要显式的调用这三个来创建基本包装类型对象
声明一个基本类型的数字值,布尔值,字符串时调用方法和添加属性时会进行一下步骤:
- 创建基本包装类型的一个实例
- 在实例上调用指定方法
- 销毁实例
- Number类型:
方法 | 返回值
- | -:
toString() | 方法可以接受一个表示基数的参数,返回一个几进制的数值的字符串表示
valueOf() | 返回对象表示的基本类型的数值
toFixed() | 方法会按照指定小数点位数返回数值的字符串表示
toExponential() | 返回数值的指数表示法的字符串形式
toPrecision() | 传入参数表示几位有效数字
- String 类型:
- 字符方法 charAt(), charCodeAt()
- 操作方法:拼接:concat(), 截取:slice(), substr(), substring()
- 位置方法: indexOf(), lastIndexOf()
- trim()方法
方法 | 返回值
| — | —: |
| charAt() | 方法接受一个表示位置的参数,返回一个该位置的字符的字符串表示 |
charCodeAt() | 方法接受一个表示位置的参数,返回一个该位置的字符的字符编码
cancat() | 拼接后的字符串
slice() | 参数1指定子字符串的开始位置,参数2子字符串到哪结束
substr() | 参数1指定子字符串的开始位置,参数2子字符串的长度
substring() | 参数1指定子字符串的开始位置,参数2子字符串到哪结束
subStr() | 传入参数表示几位有效数字