JavaScript高级程序设计读书笔记五

本笔记汇总了作者认为“JavaScript高级程序设计”这本书的前7章知识重点,仅供参考。

第5章 援用类型

小结:
对象在JavaScript中被称为援用类型的值,而且有1些内置的援用类型可以用来创建特定的对象,现扼要总结以下:

  • 援用类型与传统面向对象程序设计中的类类似,但实现不同;
  • Object是1个基础类型,其他所有类型都从Object继承了基本的行动;
  • Array类型是1组值得有序列表,同时还提供了操作和转换这些值的功能;
  • Date类型提供了有关日期和时间的信息,包括当前日期和时间和相干的计算功能;
  • RegExp类型是ECMAScript支持正则表达式的1个接口,提供了最基本的和1些高级的正则表达式工功能。

函数实际上是Function类型的实例,因此函数也是对象;而这1点正是JavaScript最有特点的地方。由于函数是对象,所以函数也具有方法,可以用来增强其行动。
由于有了基本包装类型,所以JavaScript中的基本类型值可以被当作对象来访问。3种基本包装类型分别是:Boolean、Number和String。以下是他们共同的特点:

  • 每一个包装类型都映照到同名的基本类型;
  • 在读取模式下访问基本类型值时,就会创建对应的基本包装类型的1个对象,从而方便了数据的操作;
  • 操作基本类型值的语句1经履行终了,就会立即烧毁新创建的对象。

在所有代码履行之前,作用域中就已存在两个内置对象:Global和Math。在大多数ECMAScript实现中都不能直接访问Global对象;不过,Web阅读器实现了承当该角色的window对象。全局变量和函数都是Global对象的属性。Math对象提供了很多属性和方法,用于辅助完成复杂的数学计算任务。

ECMAScript从技术上讲是1门面向对象语言,但它不具有传统的面向对象语言所支持的类和接口等基本结构。援用类型有时也被称为对象定义,由于它们描写的是1类对象所具有的属性和方法。对象是某个特定援用类型的实例

Object类型

大多数援用类型值都是Object类型的实例,Object是ECMAScript中使用最多的1个类型。创建Object实例的方式有两种。第1种是使用new操作符后跟Object构造函数,如

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

另外一种是使用对象字面量表示法,如

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

1般来讲,访问对象属性时使用的都是点表示法,JavaScript中也能够使用方括号表示法来访问对象的属性。如

alert(person["name"]); //"Nicholas" alert(person.name); //"Nicholas"

Array类型

ECMAScript中的数组与其他多数语言中的数组有着很大的区分。虽然ECMAScript数组与其他语言中的数组都是数据的有序列表,但与其他语言不同的是,ECMAScript数组的每项可以保存任何类型的数据。

表示方法
创建数组的基本方式有两种。第1种是使用Array构造函数,如果预先知道数组要保存的项目数量,也能够给构造函数传递该数量,而该数量会自动变成length属性的值;给构造函数传递值也能够创建数组。如

var colors = new Array();//空数组 var colors = new Array(20);//创建1个包括3项的数组 var colors = new Array("red","blue","green");//创建1个包括3个字符串值的数组 var names = Array("Greg");//创建1个包括1个字符串值的数组

第2种是使用数组字面量表示法。如

var colors = ["red","green"];//创建1个包括3个字符串的数组 var names = [];//创建1个空数组 var values = [1,2,];//忌讳,会创建1个包括2或3项的数组 var options = [,];//忌讳,会创建1个包括5或6项的数组

length属性
数组length的属性不是只读的,通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项。

检测数组
自从ECMAScript3作出规定后,就出现了肯定某个对象是否是数组的经典问题。对1个网页,或1个全局作用域而言,使用instanceof操作符就可以得到满意结果。

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

如果网页中包括多个框架,那实际上就存在两个以上不同的全局履行环境,从而存在两个以上不同版本的Array构造函数。如果从1个框架向另外一个框架传入1个数组,那末传入的数组与第2个框架中原生创建的数组分别具有各自不同的构造函数。为了解决这个问题,ECMAScript5新增了Array.isArray()方法。

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

转换方法

toLocaleString() :
toString() :
valueOf() :

栈方法和队列方法

ECMAScript提供了1种让数组的行动类似于其他数据结构的方法。

实现栈的方式(LIFO)

  • push(): 栈中项插入
  • pop():栈中项移除

实现队列的方法(FIFO)

  • push():向数组末端添加项
  • shift():从数组前段获得项

重排序方法

数组中已存在两个可以直接用来重排序的方法:reverse()sort()方法。

reverse()方法会反转数组项的顺序。

默许情况下,sort()方法按升序排列数组项。为了实现排序,sort()方法会调用每一个数组项的toString()转型方法,然后比较得到的字符串,以肯定如何排序。
另外,sort()方法可以接收1个比较函数作为参数。比较函数接受两个参数,如果第1个参数应当位于第2个之前则返回1个负数,如果两个参数相等则返回0,如果第1个参数应当位于第2个以后则返回1个正数。实际操作可以根据需要自行定义。如最简单的1个例子

function compare(value1,value2) { if (value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } }

只需将其作为参数传递给sort()方法便可。

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

另外,对数值类型或其valueOf()方法会返回数值类型的对象类型,可使用1个更简单的比较函数。

function compare(value1,value2) { return value2 - value1; }

操作方法

ECMAScript为操作已包括在数组中的项提供了很多内置方法。

concat()
该方法基于当前数组的所有项创建1个新数组。在没有参数时返回副本,接收参数会添加到数组末尾,如果接收的是数组,则数组每项添加到末尾。如

var colors = ["red","green","blue"]; var colors2 = colors.concat("yellow",["black","brown"]; alert(colors); //red,green,blue alert(colors2); //red,blue,yellow,black,brown

slice()
该方法能够基于当前数组的1或多个项创建1个新数组。slice()方法接收1或两个参数,即要返回项的起始和结束位置。

var colors = ["red","yellow","purple"]; var colors2 = colors.slice(1); var colors3 = colors.slice(1,4); alert(colors2); //green,purple alert(colors3); //green,yellow

splice()
该方法非常强大,用法很多。它的主要用处是向数组的中部插入项,使用方式有3中:

  • 删除:可以删除任意数量的项, 只需指定两个参数:要删除的第1项的位置和要删除的项数。例如,splice(0,2)会删除数组中的前两项。
  • 插入:可以向指定位置插入任意数量的项,只需提供3个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第4、第5,乃至任意多个项。例如splice(2,"red","green")会从当前数组的位置2开始插入字符串”red”和”green”。
  • 替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需提供3个参数:起始位置、要删除的项数和要插入的项。如果要插入多个项,可以再传入第4、第5,乃至任意多个项。例如splice(2,1,"green")会删除当前数组位置2的项,然后再从当前数组的位置2开始插入字符串”red”和”green”。

splice()方法始终都会返回1个数组,该数组中包括从原始数组中删除的项(如果没有删除任何项,则返回1个空数组)。下面的代码展现了上述3中用法:

var colors = ["red","blue"]; var removed = colors.splice(0,1); //删除第1项 alert(colors); //green,blue alert(removed); //red,返回的数组中只包括1项 removed = colors.splice(1,0,"orange"); //从位置1开始插入两项 alert(colors); //green,orange,blue alert(removed); //返回的是1个空数组 removed = colors.splice(1,"red","purple"); //插入两项,删除1项 alert(colors); //green,red,purple,blue alert(removed); //yellow,返回的数组中只包括1项

位置方法

ECMAScript5为数组实例添加了两个位置方法:indexOf()lastIndexOf()。这两个方法都接受两个参数:要查找的项和(可选的)表示查找出发点位置的索引。不同的是,indexOf()方法从数组的开头向后查找,laseIndexOf()方法则从数组的末尾开始向前查找。
这两个方法都返回要查找的项在数组中的位置,没找到返回⑴.在比较第1个参数与数组中的每项时,会使用全等操作符;也就是说,要查找的项必须严格相等。

var person = { name: "Nicholas" }; var people = [{ name: "Nicholas" }]; var morePeople = [person]; alert(people.indexOf(person)); //⑴ alert(morePeople.indexOf(person)); //0

迭代方法

ECMAScript5为数组定义了5个迭代方法。每一个方法都接受两个参数:要在每项上运行的函数和(可选的)运行该函数的作用域——影响this的值。传入这些方法中的函数会接收3个参数:数组项的值、该想在数组中的位置和数组对象本身。根据使用的方法不同,这个函数履行后的返回值可能会也可能不会影响方法的返回值。以下是这5个迭代方法的作用。

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

以上方法都不会修改数组中的包括的值。

其中,every()filter()方法最类似。

var numbers = [1,3,4,1]; var everyResult = numbers.every(function(item,index,array) { return (item > 2); }); alert(everyResult); //false var someResult = numbers.some(function(item,array) { return (item > 2); }); alert(someResult); //true

filter()简称为滤波器,作用也有点类似滤波器。可以用来过滤出符合条件项。

var numbers = [1,1]; var filterResult = numbers.filter(function(item,array) { return (item > 2); }); alert(filterResult); //[3,4,5,3]

map()可以用来创建包括的项与另外一个数组逐一对应的项。

var numbers = [1,1]; var mapResult = numbers.filter(function(item,array) { return item * 2; }); alert(mapResult); //[2,6,8,10,2]

forEach()本质上和使用for循环迭代数组1样。

var numbers = [1,1]; numbers.forEach(function(item,index,array) { //履行某些操作 });

归并方法

ECMAScript5还新增了两个归并数组的方法:reduce()reduceRight()。这两个方法都会迭代数组的所有项,然后构建1个终究返回的值。reduce()从前到后,reduceRight()从后到前。
这两个方法都接收两个参数:1个在每项上调用的函数和(可选的)作为归并基础的初始值。传给reduce()reduceRight()的函数接收4个参数:前1个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第1个参数自动传给下1项。第1次迭代产生在数组的第2项上,因此第1个参数是数组的第1项,第2个参数就是数组的第2项。
使用reduce()方法可以履行数组中所有值求和操作。

var values = [1,5]; var sum = values.reduce(function(prev,cur,array) { return prev + cur; }); alert(sum); //15

Date类型

ECMAScript中的Date类型是在初期Java中的java.util.Date类基础上构建的。为此,Date类型使用自UTC(Coordinated Universal Time,国际调和时间)1970年1月1日午夜(零时)开始经过的毫秒数来保存日期。

创建日期对象,使用new操作符和Date构造函数便可。

var now = new Date()

无参数传递时自动获得系统当前日期和时间。如果想根据特定日期时间创建日期对象,传入该日期毫秒数。为简化计算进程,ECMPScript提供两个方法:Date.parse()Date.UTC()
其中, Date.parse()接收1个表示日期的字符串。ECMA⑵62没有定义 Date.parse()应当支持哪一种日期格式,因此这个方法的行动因实现而异,而且通过时因地区而异。将地区设置为美国的阅读器通常都接受以下日期格式:

  • “月/日/年“,如6/13/2004;
  • “英文月名 日,年”,如January 12,2004;
  • “英文星期几 英文月名 日 年 时:分:秒 时区”,如Tue May 25 2004 00:00:00 GMT-0700。
  • ISO 8601 扩大格式 YYYY-MM-DDTHH:mm:ss.sssZ(例如 2004-05⑵5T00:00:00)。只有兼容ECMAScript5的实现支持这类格式。

例如:

var someDate = new Date(Date.parse("May 25,2004"));

如果传入Date.parse()方法的字符串不能表示日期,那末它会返回NaN。实际上,如果直接讲字符串传递给Date构造函数,也会在后台调用Date.parse()

Date.UTC()方法一样也返回表示日期的毫秒数。 Date.UTC()的参数分别是年份、基于0的月份(0⑴1)、月中的哪1天、小时数(0⑵3)、分钟、秒和毫秒数。前两个参数是必须的,其他默许为0。

//GMT时间2000年1月1日午夜零时 var y2k = new Date(Date.UTC(2000,0)); //GMT时间2005年5月5日下午5:55:55 var allFives = new Date(Date.UTC(2005,17,55,55));

与其他援用类型1样,日期类型继承了toLocaleString()toString()valueOf()方法。Date类型的toLocaleString()方法会依照与阅读器设置的地区相适应的格式返回日期和时间。valueOf()不返回字符串,而是返回日期的毫秒表示。

Date类型还有1些专门用于将日期格式化为字符串的方法,以下:

  • toDateString()——以特定于实现的格式显示星期几、月、日和年;
  • toTimeString()——以特定于时间的格式显示时、分、秒和时区;
  • toLocaleDateString()——以特定于地区的格式显示星期几、月、日和年;
  • toLocaleTimeString()——以特定于实现的格式显示时、分、秒;
  • toUTCString()——以特定于实现的格式显示完全的UTC日期。

其他相干日期/时间组件方法,可参考w3cschool的JavaScript Date对象

RegExp对象

ECMAScript通过RegExp类型来支持正则表达式。

var expression = / pattern / flags ;

其中的模式(pattern)部份可以是任何简单或复杂的正则表达式,可以包括字符类、限定符、分组、向前查找和反向援用。每一个正则表达式都可带有1或多个标志(flags),用以表明正则表达式的行动。正则表达式匹配模式支持3个标志。

  • g:表示全局模式(global),即模式将被用于所有字符串,而非在发现第1个匹配项是立即停止;
  • i:表示不辨别大小写(case-insensitive)模式,即在肯定匹配项是疏忽模式与字符串的大小写;
  • m:表示多行(multiline)模式,即在到达1行文本末尾时还会继续查找下1行中是不是存在与模式匹配的项。

与其他语言中的正则表达式类似,模式中使用的所有元字符都必须转义。
关于正则表达式的基本介绍,参考菜鸟教程上的正则表达式教程。
另外,关于RegExp对象的介绍,可以参考w3cschool上的JavaScript RegExp对象。在这里,就不赘述了。不管哪1门语言,在对字符串的处理上,正则表达式都是1个强大的工具,1定需要掌握。

Function类型

ECMAScript中最特殊确当属函数了,由于,函数实际上是对象!每一个函数都是Function类型的实例,而且和其他援用类型1样具有属性和方法。由于函数是对象,因此函数名实际上也是1个指向函数对象的指针,不会与某个函数绑定。

函数声明与函数表达式

解析器在向履行环境中加载数据时,对函数声明和函数表达式并不是1视同仁。解析器会率先读取函数声明,并使其履行代码之前可用(可以访问);至于函数表达式,则必须等到解析器履行到它所在的代码行,才会真正被解析履行。因此,除甚么时候可以通过变量访问函数这1点区分外,函数声明与函数表达式的语法实际上是等价的。

//使用函数声明 alert(sum(10,10)); function sum(num1,num2) { return num1 + num2; }

上例能够正常运行,由于在代码履行前,解析器就已通过1个名为函数声明提升(function declaration hoisting)的进程,读取并将函数声明添加到履行环境中。对代码求值时,JavaScript引擎在第1遍会声明函数并将他们放到源代码树的顶部。所以,即便声明函数的代码在调用它的带码后面,JavaScript引擎也能把函数声明提升到顶部。而下例函数表达式则不能运行

//使用函数表达式 alert(sum(10,10)); var sum = function(num1,num2) { return num1 + num2; }

没有重载!
由于函数是对象,函数名实际上是1个指向函数对象的指针,不会与某个函数绑定,这正是ECMAScript中没有函数重载概念的缘由。个人理解,除此以外,由于ECMAScript中的变量为疏松类型,因此对传入函数的参数类型没法加以限制,因此没法像C++或Java那样根据传入参数类型或数量选择调用函数,这也是造成ECMAScript没法重载的缘由之1。

//函数声明 function addSomeNumber(num) { return num + 100; } function addSomeNumber(num) { return num + 200; } var result = addSomeNumber(100); //300

该例声明两个同名函数,结果是后面的函数覆盖了前面的。该例与下面的代码几近没有区分:

var addSomeNumber = function (num) { return num + 100; }; addSomeNumber = function (num) { return num + 200; }; var result = addSomeNumber(100); //300

作为返回值的函数
由于ECMAScript中的函数名本身就是变量,因此函数也能够作为值来使用。便可以作为参数或返回值。

//函数作为参数 function callSomeFunction (someFunction,someArgument) { return somFunction (someArgument); } function add10 (num) { return num + 10; } var result1 = callSomeFunction (add10,10); alert(result1); //20 function getGreeting (name) { return "Hello," + name; } var result2 = callSomeFunction (getGreeting,"Nicholas"); alert(result2); //"Hello,Nicholas"

函数作为返回值是极有用的技术,是“闭包”技术的基础之1。
比较典型的如数组sort()方法的比较函数,它需要接收两个参数,比较它们的值。可使假定有1个对象数组,要根据某个对象属性排序,怎样办呢?

function createComparisonFunction (propertyName) { return function (object1,object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if (value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } }; }

该函数接收1个属性名,然后根据这个属性名来创建1个比较函数。使用以下

var data = [{name: "Zachary",age: 28},{name: "Nicholas",age: 29}]; data.sort(createComparisonFunction("name")); alert(data[0].name); //Nicholas data.sort(createComparisonFunction("age")); alert(data[0].name); //Zachary

函数内部属性(重点)
在函数内部,有两个特殊的对象:argumentsthis

arguments的主要用处是保存函数参数,这个对象还有1个名叫callee的属性,该属性是1个指针,指向具有这个arguments对象的函数。它可以完成函数体与函数名的解耦,以下面这个阶乘函数的利用:

//与函数名牢牢耦合 function factorial (num) { if (num <= 1) { return 1; } else { return num * factorial (num - 1) } } //使用arguments.callee替换函数名,消除耦合 function factorial (num) { if (num <= 1) { return 1; } else { return num * arguments.callee (num - 1) } }

这样,不管援用函数时使用的是甚么名字,都可以保证正常完成递归调用。如

var trueFactorial = factorial; factorial = function () { return 0; }; alert(trueFactiorial(5)); //120 alert(factorial(5)); //0

函数内部另外一个特殊对象是this,其行动与Java和C#中的this大致类似。即,this援用的是函数据以履行的环境对象——或也能够说是this值(当在网页的全局作用域中调用函数时,this对象援用的就是window)。以下例

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

sayColor()在全局域中定义,当在全局域中调用时,this援用的是全局对象window;当把这个函数赋给对象o并调用o.sayColor()是,this援用的是对象o

ECMAScript 5也规范化了另外一个函数对象的属性:caller。这个属性保存着调用当前函数的函数的援用,如果是在全局域中调用当前函数,它的值为null。使用方式类似于callee,在此不赘述。

函数属性和方法(重点)
ECMAScript中函数是对象,因此也有属性和方法。

每一个函数都包括两个属性:lengthprototype。其中,length表示函数希望接收的命名参数的个数;对ECMAScript中的援用类型来讲,prototype是保存他们所有实例方法的真正所在。
诸如toString()valueOf()等方法实际上都保存在prototype名下,只不过是通过各自对象的实例访问它们罢了。在创建自定义援用类型和实现继承时,prototype属性的作用极其重要。在ECMAScript 5中,prototype属性是不可枚举的,因此使用for-in没法发现。

每一个函数都包括两个非继承而来的方法:apply()call()。这两个方法都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
apply()方法接收两个参数,1个是在其中运行函数的作用域,另外一个是参数数组。其中,第2个参数可以是Array的实例,也能够是arguments对象。例如

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

call()方法与apply()方法的作用相同,他们的区分仅在于接收参数的方式不同。对call()方法而言,第1个参数是this值没有变化,变化的是其余参数都直接传递给函数。即,在使用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

ECMAScript 5还定义了1个方法:bind()。这个方法会创建1个函数的实例,其this值会被绑定到传给bind() 函数的值。例如

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

基本包装类型

和Java类似,为了便于操作基本类型值,ECMAScript也提供了3个特殊的援用类型:BooleanNumberString。每当读取1个基本类型值的时候,后台就会创建1个对应的基本包装类型的对象,从而让我们能够调用1些方法来操作这些数据。有点类似于Java的自动拆装箱进程,以String类型为例

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

在访问s1时,访问进程处于读取模式,后台自动完成以下处理:

  1. 创建String类型的1个实例;
  2. 在实例上调用指定的方法;
  3. 烧毁这个实例。

以上3个步骤可以想象成以下代码

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

以上3个步骤一样适用于BooleanNumber类型对应的布尔值和数字值。
援用类型与基本包装类型主要区分就是对象的生存期。使用new操作符创建的援用类型的实例,在履行流离开当前援用域之前1直都保存在内存中。而自动创建的基本包装类型的对象,则只存在1行代码的履行瞬间,然后立即烧毁。这意味着不能在运行时为基本类型值添加属性和方法。

Boolean类型

Boolean类型是与布尔值对应的援用类型,建议永久不要使用Boolean对象。

Number类型

除继承的方法外,Number类型还提供了1些用于将数值格式化为字符串的方。
- toFixed():按指定小数位返回数值的字符串表示。
- toExponential():返回以指数表示法表示的数值的字符串情势。
- toPrecision():返回固定大小格式,也可能返回指数格式,具体规则是看哪一种格式比较适合。该方法接收1个参数指定表示数值的所有数字的位数。

String类型

String类型提供了很多方法,用于辅助完成对ECMAScript中字符串的解析和操作。

字符方法
两个用于访问字符串中特定字符的方法时:charAt()charCodeAt()。两个方法都接收1个参数,即基于0饿字符位置。charAt()返回指定位置字符,charCodeAt()返回指定位置字符编码。

字符串操作方法
concat()
用于将1或多个字符串拼接起来,接受任意多个参数。

slice()substr()substring()
这3个方法基于字符串创建新字符串。它们都会返回被操作字符串的1个子字符串,而且也都接受1或两个参数。第1个参数指定子字符串的开始位置,第2个参数(在指定的情况下)表示子字符串到哪里结束。具体来讲,slice()substr()的第2个参数指定的是子字符串最后1个字符后面的位置。而substr()的第2个参数指定的则是返回的字符数。如果没有给这些方法传递第2个参数,则将字符串的长度作为结束位置。

var StringObject = "hello world"; alert(StringObject .slice(3)); //输出 "lo world" alert(StringObject .substring(3)); //输出 "lo world" alert(StringObject .substr(3)); //输出 "lo world" alert(StringObject .slice(3,7)); //输出 "lo w" alert(StringObject .substring(3,7)); //输出 "lo w" alert(StringObject .substr(3,7)); //输出 "lo worl"

当传递的参数是负值时,它们的行动就不尽相同了。其中,slice()方法会将传入的赋值与字符串长度相加,substr()方法将负的第1个参数加上字符串的长度,而将负的第2个参数转换为0.最后,substring()方法会把所有负值参数都转换为0.

var StringObject = "hello world"; alert(StringObject .slice(-3)); //输出 "rld" alert(StringObject .substring(-3)); //输出 "hello world" alert(StringObject .substr(-3)); //输出 "rld" alert(StringObject .slice(3,-4)); //输出 "lo w" alert(StringObject .substring(3,-4)); //输出 "hel" alert(StringObject .substr(3,-4)); //输出 "" 空字符串

字符串位置方法
有两个可以从字符串中查找子字符串的方法:indexOf()lastIndexOf()。前者从前往后搜索,后者反之。
两个方法都可接收可选的第2个参数,表明从字符串哪一个位置开始搜索。
在使用第2个参数的情况下,可以通过循环调用indexOf()lastIndexOf()来找到所有匹配的子字符串。以下:

var stringValue = "Lorem ipsum dolor sit amet,consectetur adipisicing elit"; var positions = new Array(); var pos = stringValue.indexOf("e"); while (pos > -1) { positions.push(pos); pos = stringValue.indexOf("e",pos + 1); } alert(positions); //"3,24,32,35,52"

trim()方法
该方法创建1个字符串的副本,删除前置及后缀的所有空格,然后返回结果。

字符串大小写转换方法
ECMAScript中触及字符串大小写转换的方法有4个:toLowerCase()toLocaleLowerCase()toUpperCase()toLocaleUpperCase()

字符串的模式匹配方法

match()
在字符串上调用这个方法,本质上与调用RegExpexec()方法相同。match()只接受1个参数,正则表达式或RegExp对象。和RegExp对象的exec()方法1样,match()方法会返回1个数组:数组的第1项是与全部模式匹配的字符串,以后的每项(如果有)保存着与正则表达式中的捕获组匹配的字符串。

var text = "cat,bat,sat,fat"; var pattern = /.at/; //与pattern.exec(text)相同 var matches = text.match(pattern); alert(matches.index); //0 alert(matches[0]); //"cat" alert(pattern.lastIndex); //0



search()
参数与match()方法相同,返回字符串中第1个匹配项的索引,如果没有返回⑴。

var text = "cat,fat"; var pos = text.search(/at/); alert(pos); //1



replace()
接受两个参数,第1个参数可以是1个RegExp对象或1个字符串(这个字符串不会被转换为正则表达式),第2个参数可以是1个字符串或1个函数。如果第1个参数是字符串,那末只会替换第1个字符串,想替换所有字符串只能提供1个正则表达式,并且要指定全局(g)标志。

var text = "cat,fat"; var result = text.replace("at","ond"); alert(result); //"cond,sond,fond"

如果第2个参数是字符串,那末还可使用1些特殊的字符序列,将正则表达式操作得到的值插入到结果字符串中。下表列出了ECMAScript提供的这些特殊的字符序列。

字符序列 替换文本
$$ $
$& 匹配全部模式的子字符串。与RegExp.lastMatch的值相同
$’ 匹配的子字符串之前的子字符串。与RegExp.leftContext的值相同
$` 匹配的子字符串之前的子字符串。与RegExp.rightContext的值相同
$n 匹配第n个捕获组的子字符组,其中nn等于0~9。例如,$1是匹配第1个捕获组的子字符串,$2是匹配第2个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串
$nn 匹配第nn个捕获组的子字符串,其中nn等于01~99。例如$01是匹配第1个捕获组的子字符串,$02是匹配第2个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串

通过这些特殊的字符序列,可使用最近1次匹配结果中的内容,以下

var text = "cat,fat"; result = text.replace(/(.at)/g,"word ($1)"); alert(result); //word (cat),word (bat),word(sat),word (fat)

replace()方法的第2个参数也能够是1个函数。在只有1个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递3个参数:模式的匹配项、模式匹配项在字符串中的位置和原始字符串。在正则表达式定义了多个捕获组的情况下,传递给函数的参数1次是模式的匹配项、第1个捕获组的匹配项、第2个捕获组的匹配项……,但最后两个参数依然分别是模式的匹配项在字符串中的位置和原始字符串。这个函数应当返回1个字符串,表示应当被替换的匹配项使用函数作为replace()方法的第2个参数可以实现更加精细的替换操作,以下例

\\返回html实体 function htmlEscape(text) { return text.replace(/[<>"&]/g,function(match,pos,originalText) { switch(match) { case "<": return "&lt;"; case ">": return "&gt;"; case "&": return "&amp;"; case "\"": return "&quot;" } }); } alert(htmlEscape("<p class=\"greeting\">Hello world!</p>")); //&lt;p class=&quot;greeting&quot;&gt;Hello world!&lt;/p&gt;


split()
该方法可以基于指定的分隔符将1个字符串分割成多个子字符串,并将结果放在1个数组中。分隔符可以是字符串,也能够是1个RegExp对象(这个方法不会将字符串看成正则表达式)。split()方法可以接受可选的第2个参数,用于指定数组的大小,以便确保返回的数组不会超过既定大小。

var colorText = "red,yellow"; var colors1 = colorText.split(","); //["red","yellow"] var colors2 = colorText.split(",",2); //["red","blue"] var colors3 = colorText.split(/[^\,]+/); //["",",""]

localeCompare()方法
该方法比较两个字符串,并返回以下值中的1个:

  • 如果字符串在字母表中应当排在字符串参数之前,则返回1个负数(大多数情况下是⑴,具体的值要视实现而定);
  • 如果字符串等于字符串参数,则返回0;
  • 如果字符串在字母表中应当排在字符串参数以后,则返回1个正数(大多数情况下是1,具体的值一样要使实现而定)。
var stringValue = "yellow"; alert(stringValue.localeCompare("brick")); //1 alert(stringValue.localeCompare(

相关文章

HTML代码中要想改变字体颜色,常常需要使用CSS样式表。CSS是...
HTML代码如何让字体盖住图片呢?需要使用CSS的position属性及...
HTML代码字体设置 在HTML中,我们可以使用标签来设置网页中的...
在网页设计中,HTML代码的字体和字号选择是非常重要的一个环...
HTML(Hypertext Markup Language,超文本标记语言)是一种用...
外链是指在一个网页中添加一个指向其他网站的链接,用户可以...