未加星标

JavaScript 高级程序设计笔记(五)

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏
第五章 引用类型

ECMAScript 虽然是一门面向对象的语言,但并不具备传统面向对象语言所支持的类和接口等基本结构。引用类型有时候也被称为对象定义,因为它描述的是一类对象所具有的属性和方法。

对象是某个特定引用类型的实例,新对象使用 new 操作符跟一个构造函数来创建

var person = new Object(); 5.1 Object 类型

创建 object 实例的方式有两种:

使用 new + 构造函数

var person = new Object(); person.name = "Nicholas"; person.age = 29;

使用对象字面量表示

var person = { name : "Nicholas", age : 29 };

在使用对象字面量语法时,属性名也可以使用字符串;而且通过对象字面量定义对象时,实际上不会调用 Object 构造函数

对象字面量也是向函数传递大量可选参数的首选方式。即这个参数是个对象,用字面量方式创建。具体在函数内部再判定参数的属性。

访问对象属性可以用方括号或点语法,二者区别不大。属性名中包含非字母非数字的,可以泗洪方括号来表示。

alert(person["name"]); //"Nicholas" alert(person.name); //"Nicholas" 5.2 Array 类型

ECMAScript 数组每一项可以保存任何类型的数据,而且大小是动态调整的,也就是随数据的添加自动增长。

创建一个数组也有两种方式,构造函数和字面量语法

索引数组用 方括号 + 下标 的方式

var colors = ["red", "blue", "green"]; alert(colors[0]); colors[2] = "black"; colors[3] = "brown";

数组的 lenght 属性不是只读的,我们可以人为修改这个属性从数组的末尾移除或添加新项,新项通常为 undefined

5.2.1 检测数组

检测一个对象是否为数组,曾经的 instanceof 面临多框架下不同版本 Array 存在不同构造函数的问题。所以 ECMAScript 5 新增了 Array.isArray() 方法

if (Array.isArray(value)){ // do something on array } 5.2.2 转换方法

所有对象都具有 toLocaleString(),toString() ,valueOf() 这三个方法

var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组 alert(colors.toString()); // red,blue,green alert(colors.valueOf()); // red,blue,green alert(colors); // red,blue,green

toString() 返回数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串,而 valueOf() 返回的还是数组, alert() 要接收一个字符串作为参数,所以会现在后台调用 toString()

join() 方法可以定义 分隔符 的字符串

如果数组中某一项的值是 null 或 undefined,那么转换输出的的结果中用空字符串表示

5.2.3 栈方法

ECMAScript 专门为数组提供了 push() 和 pop() 方法,push 会增加数组 length,而 pop 会减少 lenght

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" alert(colors.length); //2 5.2.4 队列方法

通过提供了 shift() 方法来实现队列的先进先出,该方法会移除并返回数组中的第一项,然后减少数组 length,它于 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

ECMAScript 还为数组提供了一个 unshift() 方法,与 shift() 作用相反,向数组的前端添加任意个项并返回数组的新长度。

5.2.5 排序

数组提供了两个排序方法: reverse() 和 sort()

reverse() 是反转数组项顺序

sort() 默认按升序排列,为了实现排序,sort() 会调用每个数组项的 toString() 转换方法,然后比较字符串排序。

var values = [0, 1, 5, 10, 15]; values.sort(); alert(values); //0,1,10,15,5

即使每一项都是数值,还是比较的字符串

sort() 还可以接收一个比较函数作为参数即 function compare(<) 是降序,function compare(>) 是升序;有点反直觉。

reverse() 和 sort() 的返回值是经过排序后的数组

5.2.6 操作方法

concat() 方法会先创建当前数组的副本,然后将接收的的参数添加到这个副本的末尾,最后返回新构造的数组,不传递参数就等于复制当前数组并返回副本。

slice() 能够基于当前数组的一个或多个项创建新的数组。slice() 方法接收一个或两个参数,即要返回项的起始和结束位置。只有一个参数表从该位置到结束,两个参数的话,到第二个参数指定位置的前一个元素为止。

slice() 参数如果是负数的话,加上长度来确定具体位置

splice() 主要用来向数组中插入项

删除:只需指定两个参数,要删除的起始位置和数量 插入:指定三个参数,起始位置,0(要删除的项),要插入的项(可以有多个,逗号隔开) 替换:指定三个参数,其实位置,要删除的项目和要插入的项目(其实就是在删除的项目位置插入)

splice() 方法始终都会返回一个数组,该数组包含从原始数组中删除的项。

5.2.7 位置方法

ECMAScript 5 为数组实例添加了两个位置方法 indexOf() 和 lastIndexOf() ,前者从头开始找,后者从末尾开始查找。找到返回索引,没找到返回 -1。查找时使用全等操作符 ===

5.2.8 迭代方法

ECMAScript 5 为数组定义了 5 个迭代方法,每一个方法都接收两个参数:每一项上执行的函数和运行该函数的作用域对象-this(可选);第一个函数参数又接受三个参数:数组项的值、该项在数组中的位置和数组对象本身。以下是 5 个迭代方法:

every():对所有项执行指定函数,全部返回 true,最终结果才是 true filter():对数组项目过滤,把运行结果为 true 的数组项过滤出来 forEach():对每一项都运行指定函数,无返回值 map():对每一项都运行指定函数,运行的结果组成新数组 some():对每一项都运行指定函数,如果有一项结果是 true,最终结果就是 true 这些迭代方法的回调都带三个参数: item , index , array ;通常我们只需要第一个,特别注意:调用的函数不小心使用了其他参数:
JavaScript 高级程序设计笔记(五)
5.2.9 归并方法

迭代所有数组项,构建一个最终的返回值

reduce() 从数组的第一项开始,遍历到最后 reduceRight() 从数组最后一项开始,遍历到第一项 5.3 Date 类型

调用 Date 构造函数但不传递参数,新创建的对象自动获得当前日期和时间。如果需要传参必须传入改日期的毫秒数(从 UTC 时间 1970.1.1 午夜至该日期止经过的毫秒数),为了简化计算过程,提供了两个函数

Date.parse() 接受一个表日期的字符串转换成毫秒数 Date.UTC() 也接受一个表日期的字符串,参数分别是年份、从 0 开始索引的月份、天(1 到 31)、小时(0 到 23)、分钟、秒、毫秒数。只有前两个参数(年和月)是必需的。

ECMAScript 5 添加了 Date.now() 方法,来返回调用该方法时的日期和毫秒数。

5.3.1 继承的方法

Date 类型也重写了 toLocaleString() 、 toString() 和 valueOf() 方法

toLocaleString():按照浏览器设置的地区相应的格式返回日期和时间 toString():返回带有时区信息的日期和时间 valueOf():根本不返回字符串,而返回日期的毫秒表示 5.3.2 日期格式化方法
JavaScript 高级程序设计笔记(五)
5.3.3 日期/时间组件方法
JavaScript 高级程序设计笔记(五)
JavaScript 高级程序设计笔记(五)
5.4 RegExp 类型

ECMAScript 通过 RegExp 类型来支持正则表达式。可以使用字面量或 RegExp 构造函数来创建正则表达式。如果使用构造函数,它接收两个参数(都是字符串):

要匹配的字符串模式 可选的标志字符串 5.4.1 RegExp 实例属性

每个 RegExp 实例都具有下列属性

global ignoreCase lastIndex multiline source 5.4.2 RegExp 实例方法

主要方法是 exec(),专为捕获组而设计的。接受一个参数,既要应用模式的字符串,然后返回包含第一个匹配项信息的数组;无匹配返回 null。返回的数组虽然是 Array 实例,但包含两个额外的属性:index 和 input。(index 表匹配项在字符串中的位置,input 表示应用正则表达式的字符串)

对于设置全局标志(g)的情况下,每次调用 exec() 都会在字符串中继续查找新匹配项

第二个方法是 test(),接受一个字符串参数。匹配返回 true,不匹配返回 false

RegExp 实例继承的 toLocaleString() 和 toString() 都会返回正则表达式的字面量,valueOf() 返回正则表达式本身。

5.4.3 RegExp 构造函数属性

构造函数也包含一些属性(其他语言看做是静态属性)。这些属性分别有一个长属性名和一个短属性名


JavaScript 高级程序设计笔记(五)
5.5 Function 类型

函数实际上是对象,每个函数都是 Function 类型的实例,与其他引用类型一样具有属性和方法。函数名实际上也是一个指向函数对象的指针。

函数声明:

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

函数表达式:

var sum = function(num1, num2){ return num1 + num2; }; 函数是对象,函数名是指针 5.5.1 没有重载(深入理解) function addSomeNumber(num){ return num + 100; } function addSomeNumber(num) { return num + 200; } var result = addSomeNumber(100); //300

函数名是指针

5.5.2 函数声明与函数表达式

解析器在向执行环境中加载数据时,解析器会率先读取函数声明,并使其在执行任何代码前可被访问。至于函数表达式必须等到解析器执行到它所在的代码行,才会真正被解释执行。

函数声明,javascript 引擎可以将函数声明提升到顶部

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

但如果是函数表达式,就不会这么做,下面代码会报错,因为只有执行到函数表达式时,sum 才能保持函数的引用。

alert(sum(10,10)); var sum = function(num1, num2){ return num1 + num2; };

函数声明和函数表达式只有这但不同

5.5.3 作为值的函数

ECMAScript 中的函数名本身就是变量,所以也可以做为值来使用。可以当做参数传递,也可以作为另一个函数的结果返回。

5.5.4 函数内部属性

函数内部有两个特殊的对象:arguments 和 this。

arguments 用来保存函数的参数,arguments 对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有 arguments 对象的函数。

举例经典阶乘运算

function factorial(num){ if (num <=1) { return 1; } else { return num * factorial(num-1); } }

这个函数的执行和函数名 factorial 耦合的太紧密了,如果改个名就无法执行了,为了解耦,可以利用 callee 属性

function factorial(num){ if (num <=1) { return 1; } else { return num * arguments.callee(num-1); } }

arguments.callee 指向的是函数体本身

函数内部的另一个特殊对象是 this,其引用的是函数执行的环境对象。(在网页的全局作用域中调用函数时,this 对象引用的就是 window)

window.color = "red"; var o = { color: "blue" }; function sayColor(){ alert(this.color); } sayColor(); //"red" o.sayColor = sayColor; o.sayColor(); //"blue"

函数名仅仅是个指针变量而已,即使在不同环境中执行,全局函数的 sayColor() 和 o.sayColor() 指向的仍是同一个函数。

ECMAScript 5 还规范化了另一个函数对象的属性:caller,这个属性中保存着调用当前函数的函数引用,如果在全局作用域中调用当前函数,这个值为 null

function outer(){ inner(); } function inner(){ alert(inner.caller); } outer();

因为是 outer() 调用了 inner ,所以 inner.caller 指向 outer()

可以使用 arguments.callee.caller 实现松耦合

function outer(){ inner(); } function inner(){ alert(arguments.callee.caller); } outer();

严格模式下,访问 arguments.callee 会导致错误

5.5.5 函数属性和方法

函数也是对象,所以也有属性和方法

属性:

length 表示函数希望接收命名参数的个数 prototype 对于引用类型而言,是保存它们所有实例方法的真正所在,如 toString() 和 valueOf() 等方法实际上都保存在 prototype 名下,只不过是通过各自对象的实例访问罢了。该属性不可枚举

每个都包含两个非继承来的方法,用做在特定作用域中调用函数,即设置函数体内 this 对象的值:

apply() 接收两个参数,一个是运行函数的作用域,另一个是参数数组(可以是 Array 实例,也可以是 arguments 对象) call() 与 apply() 方法的作用相同,区别在于接收参数的方式不同,必须将传递给函数的参数逐个列举出来 bind() 会创建一个函数实例,函数的 this 值绑定到『传入的参数对象上』

apply() 例子:

function sum(num1, num2){ return num1 + num2; } function callSum1(num1, num2){ return sum.apply(this, arguments); } function callSum2(num1, num2){ return sum.apply(this, [num1, num2]); } alert(callSum1(10,10)); //20 alert(callSum2(10,10)); //20

call() 例子:

function sum(num1, num2){ return num1 + num2; } function callSum(num1, num2){ return sum.call(this, num1, num2); } alert(callSum(10,10)); //20

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

bind() 例子

window.color = "red"; var o = { color: "blue" }; function sayColor(){ alert(this.color); } var objectSayColor = sayColor.bind(o); objectSayColor(); //blue 5.6 基本包装类型

为了方便操作基本类型值,ECMAScript 提供了 3 个特殊的 引用类型 :Boolean、Number 和 String。实际上每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能调用一些方法来操作这些数据。

var s1 = "some text"; var s2 = s1.substring(2);

虽然基本类型值不是对象,逻辑上不该有方法,但后台已经自动完成了一系列的处理。

创建 String 类型的一个实例 在实例上调用指定的方法 销毁这个实例

上面这三个步骤也分别适用于 Boolean 和 Number 类型对应的布尔值和数字值。

引用类型与基本包装类型的主要区别就是对象的生存期:

使用 new 操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。 自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。(这意味着我们不能在运行时为基本类型添加属性和方法) var s1 = "some text"; s1.color = "red"; // 为 s1 添加 color 属性时,后台会创建 String 实例对象 alert(s1.color); //undefined 上一行的 s1 对象已经销毁了,这行等于又创建了一个新的 String 对象,但是没有 color 属性

基本包装类型实例调用 typeof 会返回 object

把字符串传给 Object 构造函数,就会创建 String 实例;而传入数值会得到 Number 实例;传入布尔值参数会得到 Boolean 实例。

5.6.1 Boolean 类型

Boolean 类型是余布尔值对应的引用类型。因为它与基本类型的布尔值在一些行为上有很多不同,建议永远不要使用它。

5.6.2 Number 类型

Number 是与数字值对应的引用类型。也重写了 valueOf() 、 toLocaleString() 和 toString() 方法

还提供了一些方便的方法(毕竟封装成对象就是为了这个):

toFixed() 按照指定的小数位返回数值的字符串表示(能够四舍五入) toExponential() 返回以指数表示法(e 表示法) toPrecision() 接收一个参数(所有数字的位数,不含指数部分)可能返回固定格式,也可能返回指数格式(具体看哪种合适)

使用 typeof 测试基本类型数值时,始终会返回『number』,而测试 Number 对象时,会返回『object』

5.6.3 String 类型

String 类型是字符串的对象包装类型。提供了很多方法

字符方法 基于位置得到字符 charAt() 得到字符 charCodeAt() 得到字符编码 字符串操作方法 concat() 拼接 slice() substr() substring() 字符串位置方法 indexOf() lastIndexOf() trim() 方法 创建一个字符串副本,删除前置及后缀的所有空格,然后返回结果。 字符串大小写转换方法 toLowerCase() toLocaleLowerCase() toUpperCase() toLocaleUpperCase() 字符串的模式匹配方法 match() 接受一个参数,要么是一个正则要么是一个 RegExp 对象,返回一个数组 search() 参数同上,返回字符串中第一个匹配项的索引,没找到返回 -1 replace() 接受两个参数,第一个可以是字符串或 RegExp 对象,第二个可以是一个字符串或一个函数 split() 基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放到一个数组中 localeCompare() 方法 根据字母表比较字符串 fromCharCode() 方法 接收一或多个字符编码,转换成一个字符串,与 charCodeAt() 执行相反的操作 HTML 方法 动态格式化 HTML
JavaScript 高级程序设计笔记(五)
5.7 单体内置对象

ECMA-262 对内置对象的定义是:由 ECMAScript 实现提供的、不依赖宿主环境的对象,这些对象在 ECMAScript 程序执行之前就已经存在了。开发者不必显式地实例化内置对象,因为它们已经实例化了。前面已经介绍了大多数的内置对象,如 Object、Array 和 String。ECMA-262 还定义了两个单体内置对象: Global 和 Math

5.7.1 Global 对象

ECMAScript 中的 Global 对象在某种意义上算是一个终极的『兜底儿对象』,不属于任何其他对象的属性和方法,最终都是它的属性和方法。isNaN()、isFinite()、parseInt() 和 parseFloat() 都是 Global 对象。他还包含其他一些方法

URI 编码方法 eval() 方法,就像是一个完整的 ECMAScript 解析器,只接受一个参数,即要执行的 js 字符串,通过 eval 执行的代码被认为和 eval 具有一样的作用域(严格模式失效) Global 对象的属性
JavaScript 高级程序设计笔记(五)
windows 对象 5.7.2 Math 对象

ECMAScript 还为保存数学公式和信息提供了一个公共位置,即 Math 对象

Math 对象的属性
JavaScript 高级程序设计笔记(五)
min() 和 max() 方法 接收任意多的值,返回最小/最大 舍入方法
Math.ceil() 向上舍入 Math.floor() 向下舍入 Math.round() 四舍五入 random() 方法 返回大于等于 0 小于 1 的随机数 其他方法
JavaScript 高级程序设计笔记(五)
5.8 小结
JavaScript 高级程序设计笔记(五)

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

分页:12
转载请注明
本文标题:JavaScript 高级程序设计笔记(五)
本站链接:http://www.codesec.net/view/484456.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(31)