- 引用类型是一种数据结构,用于将数据和功能组织在一起。
- ECMAScript从技术上讲是一门面向对象语言,但它不具备传统面向对象语言所支持的类和接口等基本结构。
ECMAScript提供了很多原生引用类型,以便开发人员用以实现常见的计算任务:
Object
创建Object实例方式(两种):
1) 使用new操作符后跟object构造函数,如下:
var person = new Object();
person.name = "Nicholas";
person.age = 29;
2) 对象字面量,如下:(向函数传递大量可选参数的首选方式)
var person = {
name : "Nicholas",
age : 29
};
Array
ECMAScript数组中的每一项可以保存任何类型的数据。
创建数组方式两种:
1) 使用Array构造函数,如下(可以省略new操作符):
var colors = new Array();
var colors = new Array(20);
var colors = new Array("red", "blue", "green");
2) 使用数组字面量表示法,如下:
var colors = ["red", "blue", "green"];
检测数组
Array.isArray( )方法:最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。
if(Array.isArray(value)) {
//对数组执行某些操作
}
转换方法
所有对象都具有toLacaleString( ),toString( )和valueOf( )方法。
var colors = ["red", "blue", "green"];
alert(colors.toString());
alert(colors.valueOf());
alert(colors);
//三者输出都为:red,blue,green
join( )方法可以使用不同的分隔符来构建字符串:
var colors = ["red", "green", "blue"];
alert(colors.join(",")); //red,green,blue
alert(colors.join("||")); //red||green||blue
栈方法
var colors = new Array();
var count = colors.push("red", "green");
count = colors.push("black"); //创建数组,推入三项
alert(count); //3
var item = colors.pop();
alert(item); //"black"
alert(colors.length); //2
队列方法
var colors = new Array();
var count = colors.unshift("red", "green");
count = colors.unshift("black");
alert(count); //3
var item = colors.shift();
alert(item); //red
alret(colors.length); //2
重排序方法
1) revrese( )反转数组项顺序。如下:
var value = [1,2,3,4,5];
values.reverse();
alert(value); //5,4,3,2,1
2) sort( )按升序排列数组项,调用每个数组项的toString( )转型方法,比较得到的字符串,确定如何排序。即使数组中的每一项都是数值,sort( )方法比较的也是字符串。
var value = [0, 1, 5, 10, 15];
value.sort( );
alert(value); // 0, 1, 10, 15, 5
操作方法
1) 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
2) slice( ): 截取数组
var colors = ["red", "green", "blues", "yellow", "purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);
alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow
3) splice( ):
删除: 传入2个参数:要删除的第一项的位置和要删除的项数。
插入/替换: 传入3个参数:起始位置,要删除的项数, 要插入的项(可多项)
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
removed = colors.splice(1,1,"red","purple"); //插入两项,删除第二项
alert(colors); //green,red,purple,orange,blue
alert(removed); //yellow,返回数组中只包含一项
位置方法
1) indexOf( ):从数组开始(位置0)向后查找;lastIndexOf( )从数组末尾开始向前查找
2) 返回要查找的项在数组中的位置,或在没找到的情况下返回-1
3) 比较数组中每一项会使用全等操作符(===)
4) 传入2个参数:要查找的项和查找起点位置的索引(可选)
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3 (从位置0开始,第一个值为4的位置为3)
alert(numbers.lastIndexOf(4)); //5(从末尾开始,第一个值为4的位置为5)
alert(numbers.indexOf(4,4)); //5(从位置4开始,第一个值为4的位置为5)
alert(numbers.lastIndexOf(4,4); //3(从倒数位置4开始,第一个值为4的位置为3)
迭代方法
每个方法接收2个参数:要在每一项运行的函数(接收3个参数:数组项的值,该项在数组中的位置和数组对象本身)和运行该函数的作用域对象(可选)
every( ): 如果该函数对每一项都返回true,则返回true
filter( ): 返回该函数会返回true的项组成的数组
forEach( ): 这个方法没有返回值
map( ): 返回每次函数调用的结果组成的数组
some( ): 如果该函数对任一项返回true,则返回true
var numbers = [1,2,3,4,5,4,3,2,1];
vae everyResult = numbers.every(function(item, index, array) {
return (item > 2);
}) ;//item:数组项的值;index:该项在数组中的位置; array:数组对象本身
alert(everyResult); //false
var someResult = numbers.some(function(item, index, array){
return (item > 2);
});
alert(comeResult); //true
var filterResult = numbers.filter(function(item, index, array){
return (item > 2);
});
alert(filterResult); //[3,4,5,4,3]
var mapResult = numbers.map(function(item,index,array){
return item * 2;
});
alert(mapResult); //[2,4,6,8,10,8,6,4,2]
归并方法
1) reduce( ):从数组第一项开始,遍历到最后; reduceRight( )从数组最后一项开始,向前遍历到第一项;
2) 两个方法都接收两个参数:每一项上调用的函数(传入4个参数:前一个值,当前值,项的索引和数组对象)和作为归并基础的初始值(可选)
var values - [1,2,3,4,5];
var sum = values.reduce(function(prev,cur,index,array){
return prev + cur;
});
//prev: 前一个值; cur:当前值; index:项的索引 array: 数组对象
alert(sum); //15 reduceRight相加顺序恰好相反
Function
函数实际上是对象,每个函数都是function类型的实例,与其他引用类型一样具有属性和方法。格式:
var sum = function(num1,num2);
函数是对象,函数名是指针。 没有函数重载的概念,相同函数,后者覆盖前者。
函数属性和方法
每个函数包含两个属性:length和prototype;
length属性表示函数接受的命名参数的个数:
function sayName(name) {
alert(name);
}
function sum(num1,num2) {
return num1 + num2;
}
function sayHi() {
alert("hi");
}
alert(sayName.length); //1
alert(sum.length); //2
alert(sayHi.length); //0
prototype保存所有实例方法,如:toString( ),valueOf( )…等方法实际上都保存在prototype名下,只不过通过各自对象实例访问。
每个函数包含两个非继承而来的方法:apply( )和call( ),用途是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
apply( )传入2个参数:在其中运行函数的作用域和参数数组(可以是Array实例,也可以是arguments对象)
function sum(num1, num2) {
return num1 + num2;
}
function callSum1(num1, num2) {
return sum.apply(this, arguments); //传入arguments对象(argument包含着传入函数的所有参数)
}
function callSum2(num1, num2) {
return sum.apply(this, [num1, num2]); //传入数组
}
function callSum3(num1,num2) {
return sum.call(this, num1, num2);
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20
alert(callSum3(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
基本包装类型
引用类型:Boolean, Number, String.
每当读取一个基本类型值的时候,后台就会建立一个对应的基本包装类型的对象,让我们能够调用一些方法来操作这些数据。
var si = new String("some txt");
var s2 = s1.substring(2);
si = null;
引用类型与基本包装类型的主要区别就是对象的生存期:使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一致保存在内存中。二而自动创建的基本包装类型对象,则只存在一行代码的执行瞬间,然后立即被销毁。
var s1 = "some txt";
s1.color = "red";
alert(s1.color); //undefined
Object构造函数和工厂方法一样,根据传入值的类型返回相应基本包装类型的实例,使用new调用基本包装类型(Boolean, Number, String)的构造函数,与直接调用同名转型函数是不一样的:
var value = "25";
var number = Number(value); //转型函数
alert(typeof number); //"number"
var obj = new Number(value); //构造函数
alert(typeof obj); //"object"
//number中保存的是基本类型值;变量obj保存的是Number的实例
Boolean类型
var booleanObject = new Boolean(true);
Boolean类型的实例重写了valueof( )方法,返回基本类型true或false;重写了toString( )方法,返回字符串“true”和“false”。
基本类型与引用类型的布尔值区别:
1. typeof操作符对基本类型返回“boolean”,对引用类型返回“object”。
2. 因Boolean对象是boolean类型的实例(基本类型的数值则不是),使用instanceof操作符测试Boolean对象会返回true,而测试基本类型的布尔值则返回false。
var falseObject = new Boolean(false);
var result = falseObject && true;
//是对falseObject而不是对它的值(false)进行求值,布尔表达式中所有对象都会被转换为true,所以falseObject对象在布尔表达式中代表的是true
alert(result); //true
var falseValue = false;
alert(result); //false
alert(typeof falseObject); //object
alert(typeof falseValue); //boolean
alert(falseObject instanceof Boolean); //true
alert(falseValue instanceof Boolean); //false
Number类型
var bumberObject = new Number(10);
Number类型也重写了valueOf( ), toLocaleString( ), toString( )方法。重写后valueOf( )方法返回对象表示的基本类型的数值,另外两个方法返回字符串形式的数值。
toString( ):传递参数,返回字符串形式的结果
var num = 10;
alert(num.toString( )); //"10"
alert(num.toString(2)); //"1010" 二进制
alert(num.toString(8 )); //"12“ 八进制
alert(num.toString(10)); //"10” 十进制
alert(num.toString(16)); //"a" 十六进制
数值格式化字符串方法:
toFixed( ):按照指定的小数位返回数值的字符串:
var num = 10;
alert(num.toFixed(2)); //"10.00"
var num = 10.005
alert(num.toFixed(2)); //"10.01"
toExponential( ):返回指数表示法表示数值的字符串
var num = 10;
alert(num.toExponential(1)); //"1.0e+1"
toPrecision( ):接收一个参数,表示数值所有数字的位数(不包括指数部分)。
var num = 99;
alert(num.toPrecision(1)); //"1e+2"
alert(num.toPrecision(2)); //"99"
alert(num.toPrecision(3)); //"99.0"
与Boolean类似:不建议直接实例化Number类型
var numberObject = new Number(10);
var numberValue = 10;
alert(typeof numberObject); //"object"
alert(typeof numberValue); //"number"
alert(numberObject instanceof Number); //true
alert(numberValue instanceof Number); //false
String类型
var stringObject = new String("hello world"):
String类型中字符串解析和操作方法:
字符方法
charAt( ):以单字符字符串的形式返回给定位置的字符:
charCodeAt( ):以单字符字符串的形式返回给定位置的字符编码
var stringValue = "hello world";
alert(stringValue.charAt(1)); //"e" 字符
alert(stringValue.charCodeAt(1)); //"101" "e"的字符编码
字符串操作方法
cancat( ):将一个或多个字符串拼接起来,返回拼接得到的新的字符串(实际操作中大多数情况下用“+”操作符)
var stringValue = "hello";
var result = stringValue.concat("world","!");
alert(result); //"hello world!"
alert(stringValue); //"hello"
slice( ),substr( ), substring( ):slice( )和substring( )的第二个参数指定的是子字符串最后一个字符后面的位置,substr( )的第二个参数指的是返回字符个数。它们只是返回一个基本类型的字符串值,对原始字符串没有任何影响
var stringValus = "hello world";
alert(stringValue.slice(3)); //"lo world"
alert(stringValue.substring(3)); //"lo world"
alert(stringValue.substr(3)); //"lo world"
alert(stringValue.slice(3,7)); //"lo w"
alert(stringValue.substring(3,7)); //"lo w"
alert(stringValue.substr(3,7)); //"lo worl"
如果传入参数为负数,slice( )会 将传入负值与字符串的长度相加;substr( )方法将负的第一个参数加上字符串长度;将负的第二个参数转换为0;substring( )会把所有负值参数都转换为0。
var stringValue = "hello world";
alert(stringValue.slice(-3)); //"rld"
alert(stringValue.substring(-3)); //"hello world"
alert(stringValue.substr(-3)); //"rld"
alert(stringValue.slice(3,-4)); //"lo w"
alert(stringValue.substring(3,-4)); //"hel" 函数变成了substring(3,0),将较小数作为开始位置,较大数作为结束位置,最终调用了substring(0,3)
alert(stringValue.substr(3,-4)); //" "(返回包含零个字符的字符串)
字符串位置方法
字符串中查找子字符串方法:indexOf( )和lastindexOf( )。indexOf( )从字符串开头向后搜索子字符串, lastIndexOf( )方法从字符串末尾向前搜索子字符串(接收可选的第二个参数,表示从字符串中的哪个位置开始搜索,忽略该位置之前的所有字符)
var stringValue = "hello world";
alert(stringValue.indexOf("o")); //4
alert(stringValue.lastIndexOf("o"));//7
大小写转换方法
var stringValue = "hello world";
alert(stringValue.toLocaleUpperCase()); //"HELLO WORLD"
alert(stringValue.toUpperCase()); //"HELLO WORLD"
alert(stringValue.toLocaleLowerCase()); //"hello world"
alert(stringValue.toLowerCase()); //"hello world"
//toUpperCase() & toLowerCase() 是经典方法。toLocaleUpperCase() & toLocaleLowerCase()针对特定地区实现,在不知道自己代码将在何种语言下运行,推荐使用地区方法
单体内置对象
由ECMAScript实现提供,不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在。(开发人员不必显示地实例化内置对象,因为它们已经实例化了,例如: Object,array,string),ECMA-262还定义了两个单体内置对象:Global和Math
Global
不属于任何其他对象的属性和方法,最终都是它的属性和方法
URI(通用资源标识符)编码方法
有效的URI中不能包含某些字符(例如空格),利用Global对象中的encodeURI( )和encodeURIComponent( )方法对URI进行编码(利用UTF-8编码替换所有无效字符),以便发送给浏览器。
encodeURI( )主要用于整个URI,不会对本身属于URI的特殊字符进行编码,例如冒号,正斜杠,问号,井字号
encodeURIComponent( )主要用于对URI中某一段进行编码,会对它发现的任何非标准字符进行编码
var uri = "http://www.wrox.com/illegal value.htm#start";
//"http://www.wrox.com/illegal%20value.htm#start"
alert(encodeURI(uri));
//"http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start"
alert(encodeURIComponent(uri));
/*
1. encodeURI( )除了空格之外其他字符都原封不动,只有空格被替换成了%20。
2. encodeURIComponent() 会使用对应的编码替换所有非字母数字字符。
3. 这也正是前者可以对整个uri使用,后者只能对附加现有URI后面的字符串使用。*/
与encodeURI( )和 encodeURIComponent( )对应的方法为decodeURI( )和decodeURIComponent( )。 作用恰好相反,对替换字符进行解码。
eval( )方法
像是完整的ECMAScript解析器,只接受一个参数,即要执行的ECMAScript字符串,将传入的参数当作实际ECMAScript语句解析,把执行的结果插入原位置。
eval("alert('hi'))"; 等价于 alert("hi");