引用类型的值(对象)是引用类型的一个实例,引用类型是一种数据结构
创建 Object 实例的方式有两种:
-
使用 new 操作符后跟 Object 构造函数
var person = new Object()
-
使用对象字面量表示法
var person = { name: "Ada", age: 28 }
其中属性名也可以使用字符串
通过对象字面量定义对象时,实际上不会调用 Object 构造函数 最好的做法是对必需值使用命名参数,然后使用对象字面量封装多个可选参数。
alert(person.name);
alert(person["name"]); // 如果属性中包含会导致语法错误的字符(如空格),或者属性使用的是关键字或保留字,就需要使用方括号表示法
ECMAScript 数组的每一项可以保存任何类型的数值,并且数组大小可以动态调整,随着数据的增加自动增长
- 使用 Array 构造函数
var colors = new Array(); // new 可以省略
- 使用数组字面量表示法
var colors = ["red", "blue", "green"]; // 不要在最后一项后面添加括号
使用数组字面量表示法时,也不会调用 Array 构造函数
colors[4] = "black";
- 如果数组长度小于5,会将这个数组的长度增加到5,第五项值为 "black",其他项为 undefined
- 如果数组长度大于5,会将这个数组的第五项的值修改为 "black"
数组的 length 属性不是只读的,可以通过修改这个属性向数组删除项或者添加新项
colors[colors.length] = "black"; //向数组最后增添值为 "black" 的新项
数组最多可容纳 4 294 967 295 个项,几乎能够满足任何编程需求了。
if (value instanceof Array) {
// 对数组进行操作
}
instanceof 操作符的问题在于,它假定只有一个全局环境,如果网页包含多个框架就会产生问题。
ES5 新增了 Array.isArray() 方法来确定某个值到底是不是数组。
if (Array.isArray(value)) {
// 对数组进行操作
}
- toString():返回一个以逗号分隔数组每一项的字符串
- valueOf():返回的是数组原始值
- toLocaleString()
- join():接受一个参数,以字符串形式传入分隔符,返回一个以分隔符分隔每一项的字符串,未传入值的话默认使用逗号
ECMAScript 专门为数组提供了 push() 和 pop() 方法,用来实现类似栈的行为
- push():向数组末端添加项
- shift():移除数组第一个项并将其返回
- unshift():向数组前端添加项并返回新数组的长度
反转数组顺序,返回排序后的数组
调用每一项的 toString() 方法,比较得到的字符串,然后返回排序后的数组
默认情况下升序排列,可以传入一个比较函数作为参数以指定比较方法
// 升序
function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
// 降序
function compare(value1, value2) {
if (value1 < value2) {
return 1;
} else if (value1 > value2) {
return -1;
} else {
return 0;
}
}
为当前数组创建一个副本,将传入参数添加到它的末尾,返回该数组
第一个参数是起始位置,第二个参数是结束位置。该方法会获得从起始位置到结束位置(不包括结束位置的项)的所有项返回一个新数组。如果没有第二个参数,则一直返回到数组末尾。如果结束位置小于起始位置则返回一个空数组。
传入三个参数:起始位置,要操作的项数,新的项
- 只有前两个参数则会执行删除操作
- 第二项为 0 则会执行插入操作
- 三个参数都有则会执行替换操作,插入项数不必与删除项数相等 该方法返回一个数组,包括从原始数组中删除的项(没有删除项则返回空数组)
比较参数与数组中每一项时使用全等比较,没找到时返回-1
每个方法接受两个参数:在每一项上调用的函数、运行函数的作用于对象(可选)
传入的函数接受三个参数:数组项的值、该项在数组中的位置、数组对象本身
arr.every(function(item, index, array))
- every():对数组中每一项运行给定函数,如果函数对每一项都返回 true,则返回 true
- filter():对数组中每一项运行给定函数,将会返回 true 的项组成新数组返回
- forEach():对数组中每一项运行给定函数,没有返回值,本质上与 for 循环迭代数组一样
- map():对数组中每一项运行给定函数,返回函数对每一项的调用结果
- some():对数组中每一项运行给定函数,如果函数调用任何一项返回 true,该函数返回 true
每个方法接受两个参数:在每一项上调用的函数、作为归并基础的初始值(可选)
传入的函数接受四个参数:前一个值、当前值、项的索引、数组对象
arr.reduce(function(prev, cur, index, array))
使用 UTC 时间 (Coordinated Universal Time 国际协调时间) 1970年1月1日零时开始经过的毫秒数
var now = new Date(); // 构造函数不传参情况下自动获取当前时间
- Date.parse() 方法接受一个表示日期的字符串参数,返回相应日期的毫秒数;如果传入参数不能表示日期,会返回 NaN。实际上直接使用 Date 构造函数传入字符串参数,也会在后台调用 Date.parse() 方法。
- Date.UTC():同样返回毫秒数,但传参不同(年份、0
11的月份、131的日子、0~23的小时、分钟、秒、毫秒),省略的参数视为0 - ES5 增加了 Date.now() 方法
- toString():返回带有时区信息的日期时间,例如 PST,小时范围 0~23
- toLocaleString():按照浏览器地区返回相应日期时间,没有地区信息,会包含 AM 或 PM
- valueOf():不返回字符串,返回毫秒表示
- toDateString()
- toTimeString()
- toLocaleDateString()
- toUTCString()
getTime()
var expression = / pattern / flags ;
var words = /[bc]at/gi; // 匹配所有"bat"和"cat",不区分大小写
正则表达式部分,可带有一个或者多个标志
- g :表示全局(global)模式
- i :表示不区分大小写(case-insensitive)模式
- m :表示多行(multiline)模式
( [ { \ ^ $ | ) ? * + . ] }
正则表达式中所有元字符都必须转义
字面量形式定义或 RegExp 构造函数
RegExp 构造函数接受两个参数:要匹配的正则表达式字符串、可选的标志字符串
var words = new RegExp("[bc]at", "ig");
由于参数是字符串,所有元字符需要双重转义
- global:布尔值,表示是否设置了 g 标志
- ignoreCase:布尔值,表示是否设置了 i 标志
- lastIndex:整数,表示开始搜索下一个匹配项的字符位置
- multiline:布尔值,表示是否设置了 m 标志
- source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回
- exec()
注意在 exec() 方法中,每次都只返回一个匹配项,如果没有应用全局标志,每次都返回第一个匹配项,如果应用了全局标志,每次返回下一个匹配项
var text = "mom and dad and baby"; var pattern = /mom( and dad( and baby)?)?/gi; var matches = pattern.exec(text); console.log(matches.index); // 0 console.log(matches[0]); // "mom and dad and baby" console.log(matches[2]); // " and baby"
- test()
该方法返回的是布尔值(是否匹配)
var text = "000-00-0000"; var pattern = /\d{3}-\d{2}-\d{4}/; if (pattern.test(text)) { alert("The pattern was matched."); }
- toString() 与 toLocaleString() 都会返回正则表达式的字面量
- valueOf() 返回正则表达式本身
正则表达式的属性都有一个长属性名和一个短属性名
长属性名 | 短属性名 | 说明 |
---|---|---|
input | $_ | 最近一次要匹配的字符串 |
lastMatch | $& | 最近一次的匹配项 |
lastParen | $+ | 最近一次匹配的捕获组 |
leftContext | $` | input中lastMatch之前的文本 |
multiline | $* | 布尔值,是否使用多行模式 |
rightContext | $' | input中lastMatch之后的文本 |
实际上,函数的类型是对象,每个函数都是 Function 类型的实例,与其他引用类型一样具有属性和方法。
函数名实际上是指向函数对象的指针,不会与某个函数绑定
-
函数声明
function sum (num1, num2) {return num1 + num2}
-
函数表达式
var sum = function(num1, num2) {return num1 + num2}
-
构造函数
var sum = new Function("num1", "num2", "return num1 + num2")
不推荐,因为导致解析了两次代码,需要解析字符串,影响性能
解析器会先读取函数声明,使其在执行任何代码前就已经可以访问,而函数表达式则需要等执行到所在代码行才会被解释执行。
alert(sum(10, 10)); // 可以正常运行
function sum(num1, num2) {
return num1 + num2;
}
ECMAScript 中的函数本身就是变量,所以也可以当作值来使用
注意:如果想要访问函数的指针但并不执行函数,需要去掉函数名后面的括号
主要用途是保存函数参数
是一个指针,指向拥有这个 arguments 对象的函数
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num-1)
}
}
如上面的例子,在递归调用中使用 argumnets.callee 属性,可以解除紧耦合状态,保证递归正常进行。
注意:严格模式下访问该属性会报错
this 引用的是函数据以执行的环境对象
函数的名字仅仅是一个包含指针的变量,即使是在不同的环境中执行,也会指向同一个函数
保存着调用当前函数的函数的引用,如果在全局作用域中调用当前函数,它的值为 null。
注意:在严格模式中不能为函数的 caller 属性赋值,会报错。
ECMAScript 中的函数是对象,每个函数都包含两个属性:length 和 prototype
对于 ECMAScript 中的引用类型来说,prototype 是保存它们所有实例方法的真正所在。也就是说,像 toString()、valueOf() 这些方法实际上都保存在 prototype 名下,只是通过各自对象的实例进行访问而已。
在 ES5 中,prototype 属性是不可枚举的,因此无法用 for-in 实现
每个函数都包含两个非继承而来的方法:apply() 和 call(),作用都是设置函数体内 this 对象的值。
接受两个参数:运行函数的作用域,参数数组。其中参数数组可以是 Array 的实例,也可以是 arguments 对象。
foo.apply(this, [blue, red, green]);
接受的参数:运行函数的作用域,其余参数逐个列出。
foo.call(this, blue, red, green);
实际上,apply() 与 call() 真正强大的地方在于能够扩充函数赖以运行的作用域,而且这样使用对象不需要和方法有任何的耦合关系。看以下例子:
window.color = "red";
var o = { color: "blue" };
function sayColor() {
alert(this.color);
}
sayColor(); // red
sayColor.call(this); // red
sayColor.call(window); // red
sayColor.call(o); // blue
创建一个函数实例,this 值会被绑定到传入的参数上
为了方便操作基本类型值,ECMAScript 提供了三个特殊引用类型:Boolean、Number、String
引用类型与基本包装类型的主要区别就是生存期,引用类型在离开当前作用域前都一直存在,基本包装类型只存在于代码执行的一瞬间,然后立刻被销毁。因此我们不能为基本包装类型添加属性和方法。
Object 构造函数会根据传入值的类型返回相应基本包装类型的实例。例如:
var obj = new Object("some text");
alert(obj instanceof String); // true
重写了 valueOf() 方法,返回 true 或 false;重写了 toString() 方法,返回字符串 "true" 和 "false"。
容易造成误解,建议永远不要使用。
重写了 valueOf() 方法,返回基本数值;重写 toString() 方法,返回字符串形式的数值。
提供了将数值格式化为字符串的方法:
- toFixed():按照传入参数返回指定小数位数的数值的字符串表示,能够自动舍入
- toExponential():返回以指数表示法(e表示法)表示的数值的字符串形式,传入的参数同样是用于指定小数位数
- toPrecision():根据要处理的数值决定到底调用哪个方法
继承的 valueOf() toString() toLocaleString() 方法都返回对象表示的字符串
- charAt():以字符串形式返回给定位置的字符
- charCodeAt():以字符串形式返回给定位置的字符编码
- concat():用于将一个或多个字符串拼接起来,返回拼接得到的新字符串,可以接受任意多个参数
- slice():返回从开始位置到结束位置所有的项组成的新字符串。如果传入参数为负值,会将负值与字符串长度相加。
- substring():返回从开始位置到结束位置所有的项组成的新字符串。如果传入参数为负值,会将其转换为0(注意该方法会自动将较小的值作为开始位置,较大的值作为结束位置)。
- substr():返回从开始位置起n个项组成的新字符串。如果第一个参数为负值,会给它加上字符串长度,如果第二个参数为负值,则转换为0。
indexOf() 与 lastIndexOf() 都可以接受第二个参数,指定从哪个位置开始搜索
创建一个副本,删除前置及后缀的所有空格,返回结果
- toLowerCase()
- toLocaleLowerCase()
- toUpperCase()
- toLocaleUpperCase()
- match():返回一个数组,第一项是与整个模式匹配的字符串,之后的每一项保存着捕获匹配的字符串。只接受一个参数:正则表达式 或 RegExp 对象。 本质与正则表达式的 exec() 方法相同
- search():返回字符串中第一个匹配项的索引,如果没有找到匹配项则返回-1。接受的参数与 match() 相同。
- replace():接受两个参数:第一个参数可以是 RegExp 对象或者字符串,第二个参数可以是字符串或者函数。 如果第一个参数是字符串,那么只会替换第一个子字符串,想要替换所有字符串需要用指定全局模式的正则表达式。
- split():基于指定的分隔符将一个字符串分割为多个子字符串,将结果以数组形式返回。分隔符可以是字符串也可以是 RegExp 对象。可以传入第二个参数指定数组大小。
比较两个字符串:
- 如果字符串在字母表中排在字符串参数前,则返回一个负数(一般是-1)
- 如果字符串等于字符串参数,则返回0
- 如果字符串在字母表中排在字符串参数后,则返回一个正数(一般是1)
接受一个或多个字符编码,将其转换为一个字符串
定义:由 ECMAScript 实现提供的、不依赖于宿主环境的对象,这些对象在 ECMAScript 程序执行前就已经存在了。例如 Object、Array、String、Global、Math
不属于任何其他对象的属性和方法最终都属于 Global 对象,所有在全局作用域中定义的属性和函数都是 Global 对象的属性。例如 isNaN()、parseInt()。
- encodeURI():主要用于整个 URI,不会对本身属于 URI 的特殊字符编码(如冒号、问号、井号、正斜杠)。
- encodeComponent():主要用于对 URI 中某一段进行编码,会对任何非标准字符进行编码。该方法使用更多。 相对应有解码用的 decodeURI() 和 decodeComponent()
会将传入对象当作实际的 ECMAScript 语句来解析,然后把执行结果插入到原位置。被执行的代码具有与 eval() 执行环境相同的作用域链。
在 eval() 中创建的任何变量或函数都不会被提升,它们只在 eval() 执行的时候创建。
在严格模式下,外部访问不到 eval() 中创建的任何变量或函数,为 eval 赋值也会导致错误。
注意:使用 eval() 有代码注入的危险。
特殊值(如 undefined、NaN、Infinity)和构造函数(如 Object、Function、RegExp、Error 等)都是 Global 对象的属性
Web 浏览器将 Global 对象作为 window 对象的一部分加以实现。
一种取得 Global 对象的方法:
var global = function() {
return this;
} ();
为了保存数学公式和信息提供的公共位置,比用 JS 编写函数计算快得多
属性 | 说明 |
---|---|
Math.E | 自然对数的底数 |
Math.LN10 | 10的自然对数 |
Math.LOG2E | 以2为底e的对数 |
Math.PI | Π的值 |
Math.SQRT1_2 | 1/2的平方根 |
Math.SQRT2 | 2的平方根 |
要找到数组中的最大或最小值可以用 apply() 方法
var values = [1, 2, 3, 4, 5, 6];
var max = Math.max.apply(Math, values);
- Math.ceil():向上舍入
- Math.floor():向下舍入
- Math.round():标准舍入(四舍五入)
Math.random() 方法返回大于0小于1的一个随机数。
可以套用以下公式从某个整数范围内随机选择一个值。
值 = Math.floor(Math.random() * 可能值得总数 + 第一个可能的值)