Object类型
我们看到的大多数引用类型值都是Object类型的实例,创建Object实例的方式有两种。
1)使用new操作符后跟Object构造函数
var person=new Object(); or var person={ };
person.name="Clarissa";
person.age=24;
2)对象字面量
var person={
name:"zhangling",
age:24 }
或者(属性名也可以用字符串)
var person={
"name":"zhangling",
"age":24 }
来看一个小例子
function displayInfo(args){
var output="";
if(typeof args.name=="string"){
output+="Name:"+args.name+'\n';
}
if(typeof args.age=="number"){
output+="Age:"+args.age+'\n';
}
alert(output);
}
displayInfo({
name:"clarissa",
age:24
});
以上也可以写成
var c={name:"clarissa",age:24}
displayInfo(c);
对必需值使用命名参数
displayInfo({
name:"stamhe",
age:31
});
而使用对象字面量来封装多个可选参数。
一般来说,访问对象属性时使用的都是点表示法,还有一种是方括号表示法:
ex:alert(person["name"]); //方括号表示法,这种可以通过变量来访问属性,可以通过变量来访问属性
var propertyName="name";
alert(person[propertyName]);
alert(person.name) ; //点表示法(常用)
Array类型
创建数组的基本方式有两种,第一种是使用Array构造函数
ex:var colors=new Array(); //new可省略
var colors=new Array("red","blue","yellow"); //创建一个包含3个字符串值的数组
var colors=new Array(3); //创建一个包含3项的数组
创建数组的第二种基本方式是数组字面量表示法
ex:var colors=["red',"blue","yellow","green","orange"];
length属性
数组的length是可读可写的
ex:var colors=["red",'blue","yellow"];
colors.length=2;
alert(colors[2]) //undefined;
var colors=["red","blue","yellow"];
colors.length=4;
alert(colors[3]); //undefined; 新增的每一项都会取得undefined值
利用length在数组末尾添加新项
var colors=["red","blue","yellow"];
colors[colors.length]="orange";
colors[colors.length]="grey" ;
colors[99]="white";
alert( colors.length); //100;
当把一个值放在超出当前数组大小的位置上时,数组就会重新计算其长度值,即长度值等于最后一项的索引加1;
转换方法
调用数组的toString()和valueOf()方法会返回相同的值,即由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。
ex: var colors=["red","blue","yellow"];
alert(colors.toString()); // red,blue,yellow
alert(colors.valueOf()); // red,blue,yellow
alert(colors); // red,blue,yellow 后台会调用toString方法
join方法
ex: var colors=["red","blue","yellow"];
alert(colors.join("|"); // red|blue|yellow
栈方法
栈是一种先入后出的数据结构
push()方法可以接收任意数量的参数,把它们爱个添加到数组末尾,并返回修改后数组的长度
pop()则从数组末尾移除最后一项,减少数组 的length值,然后返回移除的项。
ex:var colors=new Array();
var count=colors.push("red","blue");alert(count) //2;
count=colors.push("black");
alert(count); //3
var item=colors.pop();
alert(item); // "black" 移除末尾项
alert(colors.length); //2
队列方法
队列数据结构的访问规则是先进先出。
shift()它能够移除数组中的第一项并返回该项,同时将数组长度减1 .
ex:var colors=new Array();
var count=colors.push("red","green");
alert(count); //2
count=coors.push("black");
alert(count); //3;
var item=colors.shift();
alert(item); //red;
alert(colors.length); //2
unshift()与shift的用途相反;它能在数组前端添加任意个项并返回新数组的长度;
ex:var colors=new Array();
var count=colors.unshift("red","green");
alert(count); //2;
count=colors.unshift("black");
alert(count); //3;
var item=colors.pop();
alert(item); //"green";
alert(colors.item); //2
重排序方法
reverse() 降序排列
sort()升序排列
他们会调用每个数组项的toString()转型方法,然后比较得到的字符串,确定如何排序,即使数组中的每一项都是数值,他们方法比较的也是字符串。
sort方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。
ex: function compare(num1,num2){
if(num1<num2){
return -1;
}else if(num1>num2){
return 1;} else{
return 0;}
}
或者
function compare(num1,num2){
return num1-num2;
}
var values=[0,1,5,10,15];
values.sort(compare);
alert(values); //0,1,5,10,15
reverse()方法,直接在此基础上直接reverse()即可。
操作方法
concat()方法可以基于当前数组中的所有项创建一个新数组,这个方法会先创建当前数组一个副 本,然后将接收到参数添加到这个副本的末尾,最后返回新构建的数组
var colors=["red","green","blue"];
var colors2=colors.concat("yellow",["black","brown"]);
alert(colors);//red,green,blue 原数组colors保持不变
alert(colors2); //red,green,blue,yellow,black,brown
slice()方法
slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下,slice()方法返回从该参数指定位置开始至当前数组末尾的所有项。如果 有两个参数,该方法返回起始和结束位置之间的项--但不包括结束位置的项,且slice()方法不会影响原数组..如果slice()方法的参数中有一个负数,则用数组长度加上该
数来确定相应的位置。
ex: var colors=["red","green","blue","yellow","purple"];
var colors2=colors.slice(1);
var colors3=colors.slice(1,4);
var colors4=colors.slice(-4,-1);//slice(1,4)
alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow
alert(colors4); //green,blue,yellow
splice()方法
删除:可以删除任意数量的项,只需指定2个参数:要删除的第一项的位置和要删除的项数
插入:可以向指定位置插入任意数量的项,只需提供3个参数:起始位置、0、要插入的项,也可以传入多个项。
替换: 可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定3个参数: 起始位置、要删除的项数和要插入的任意数量的项。
ex: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");
alert(colors); //green,yellow,orange,blue 从位置1开始插入两项
alert(removed);//返回一个空数组
Function类型
函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针, 不会与某个函数绑定。
函数的三种表达方式,函数声明语定的函数
ex: function sum(num1,num2){
return num1+num2;
}
函数表达式定义的函数
var sum=function(num1,num2){
return num1+num2;
}; //函数末尾有一个分号,就像声明其他变量时一样
使用Function构造函数
var sum=new Function("num1","num2","return num1+num2"); //不推荐,会导致解析两次代码
一个函数可以有多个名字
ex: function sum(num1,num2){
return num1+num2;
}
alert(sum(10,10)); //20
var anotherSum=sum; //使用不带圆括号的函数名是访问函数指针,而非调用函数,此时anotherSum与sum就指向了同一个函数.
alert(anotherSum(10,10)); //20
sum=null;
alert(anotherSum(10,10)); //20
没有重载
ex:function addSomeNumber(num){
return num+100;}
function addSomeNumber(num){
return num+200;}
var result=addSomeNumber(100); //300
我们再来看一下下面的代码就可以知道原因了
var addSomeNumber=function(num){
return num+100;}
var addSomeNumber=function(num){
return num+200;}
var result=addSomeNumber(100);//300
实际上就是创建第二个函数时,覆盖了引用第一个函数的变量addSomeNumber.
函数声明与函数表达式
解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行任何代码 之前可用;至于函数表达式,则必须等到 解析器执行到它所在的代码行才会真正被解释执行。
ex: alert(sum(10,10));
function sum(num1,num2){
return num1+num2;
} //代码完全可以正常运行,因为在代码开始执行之前,解析器就已经读取函数声明并将其添加到执行环境中。
alert(sum(10,10));
function sum=function(num1,num2){
return num1+num2;
}; //会在运行期间产生错误,原因在于函数位于一个初始化语句中,而不是一个函数声明,换句话说,在执行到函数所在的语句之前,变量sum中不会保存有对函数的引 用
作为值的函数
因为ECMAScript中的函数名本身就是变量,所以函数也可以作为值来使用,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的 结果返回。
ex:function callSomeFunction(someFunction,someArgument){
return someFunction(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"
ex: function createComparisonFunction(propertyName){
return function(object1,object2){ //当时看到这里有个疑问,其实我们可以把object1对应成{name:"Zachary",age:28},object2同理。
var value1=object1[propertyName];
var value2=object2[propertyName];
if(value1<value2){
return -1;
}else if(value1>value2){
return 1;
}else{
return 0;
}
}
}
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
函数内部属性
在函数内部,有两个特殊的对象:arguments和this, 它是一个类数组对象,包含着传入函数中的所有参数,这个对象还有一个名叫callee的属性,该属性是一个指针,指向 拥有这个arguments对象的函数。
ex:function factorial(num){
if(num<=1){
return 1;
} else{
return num*factorial(num-1);
在函数有名字,而且名字以后也不会变的情况下,这样定义没有问题,但问题是这个函数的执行与函数名facgorial紧紧耦合在了一起,为了消除这种紧密耦合的现象
ex:function factorial(num){
if(num<=1){
return 1;
} else{
return num*arguments.callee(num-1);}} //这样无论引用函数时使用的是什么名字,都可以保证正常完成递归调用。
ex:var trueFactorial=factorial;
factorial=function(){
return 0;
}
alert(trueFactorial(5)); //120
alert(factorial(5)); //0
this引用的是函数据以执行操作的对象,this是函数在执行时所处的作用域(当在网页的全局作用域中调用函数时,this对象引用的就是window)
window.color="red";
var o={color:"blue"};
function sayColor(){
alert(this.color);
}
sayColor(); //red window.color
o.sayColor=sayColor;
o.sayColor(); //blue o.color
函数属性和方法
ECMAScript中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性:length和prototype. 其中,length属性表示函数希望接收的命名参数的个数
ex:function sayName(name){
alert(name);
}
alert(sayName.length);
对ECMAScript中的引用类型而言,prototype是保存它们所有实例方法的真正所在。每个函数都包含两个非继承而来的方法:apply()和call()
apply()方法接受两个参数:一个是在其运行函数的作用域,另一个参数数组。其中,第二个参数可以是Array实例,也可以是arguments对象
function sum(num1,num2){
this.name='zhangling';
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方法时,传递给函数的参数必须逐个列出来
ex: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还提供了3个特殊的引用类型;Boolean,Number和String.实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包 装类型的对象
var s1="some text";
var s2=s1.substring(2);
基本类型值不是对象,因而从逻辑上讲它们不应该有方法。然后为了让我们实现这种直观的操作,后台已经自动完成了一系列的处理。
1)创建String类型的一个实例; var s1=new String("some text");
2)在实例上调用指定的方法; var s2=s1.substring(2);
3)销毁这个实例 ; s1=null;
经过此番处理,基本的字符串值就变得跟对象一样了。而且这上面三个步骤也分别适用于Boolean和Number类型对应的布尔值和数字值。
引用类型与基本包装类型的主要区别就是对象的生存期,使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中,而自动创建的基本包 装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。这意味着我们不能在运行时为基本类型值添加属性和方法。
ex:var s1="some text";
s1.color="red";
alert(s1.color);
对基本包装类型的实例调用typeof会返回"object",而且所有基本包装类型的对象在布尔环境中都会被转换为布尔值true;
Boolean类型
Boolean是与布尔值对应的引用类型。要创建Boolean对象,可以像下面这样调用Boolean构造函数并传入true或false值;
var booleanObject=new Boolean(true);
Boolean类型的实例重写了valueOf()方法,返回基本类型值true或false:重写了valueOf()方法,返回基本类型值true或false,重写了toString()方法,返回字符串”true"和“false"
基本类型与引用类型的布尔值还有两个区别。首先,typeof操作符对基本类型返回”boolean",而对引用类型值返回“Object",其次,由于Boolean对象是Boolean类型的实例,所 以使用instanceof操作符测试Boolean对象会返回true,而测试基本类型的布尔值则返回false.
Number类型
Number是与数字值对应的引用类型。要创建Number对象,可以在调用Number构造函数时向其中传递相应的数值。下面是一个例子:
var numberObject=new Number(10);
与Boolean类型一样,Number类型也重写了ValueOf()、toLocalString()、toString()方法。重写后的valueOf()方法返回对象表示的基本类型的数值,另外两个方法则返回字符 串形式的数值
toFixed()方法会按照指定的小数位返回数值的字符串表示
ex: var num=10;
alert(num.toFixed(2));//10.00
String类型
String类型是字符串的对象包装类型,可以像下面这样使用String构造函数来创建:
var stringObject=new String("hello,world");
String类型的每个实例都有一个length属性,表示字符串包含多个字符
var stringValue="hello world";
alert(stringValue.length); //11
1.字符方法
两个用于访问字符串中特定字符的方法是:charAt() 输出字符和charCodeAt() 输出字符编码.这两个方法都接收一个参数,即基于0的字符位置。
ex:var stringValue="hello,world";
alert(stringValue.charAt(1));//"e"
2.字符串操作方法
concat()方法用于将一或多个字符串拼接起来,返回拼接得到的新字符串
ex:var stringValue="hello";
var result=stringValue.concat("world");
alert(result); //"hello,world"
alert(stringValue); //"hello"
通过stringValue调用concat()方法返回的结果是”hello,world"---但stringValue的值保持不变。实际上,concat()方法可以接受任意多个参数
var stringValue="hello";
var result=stringValue.concat("world,"!");
alert(result);
alert(stringValue);
slice()、substr()、substring() 这三个方法都会返回操作字符串的一个子字符口中 ,而且也都接受一或两个参数。第一个参数指定子字符串的开始位置,第二个参数(在指定情 况下)表示子字符串到哪里结束。与concat()方法一样,slice()、substr()、substring()方法也不会修改字符串本身的值。它们只是返回一个基本类型的字符串值
slice()和substring()的第二个参数指定的是子字符串最后一个字符后面的位置。
substr()的第二个参数指定的则是返回的字符个数。
var stringValue="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(stringVale.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" 自动调用了(0,3)
alert(stringValue.substr(3,-4)); //""空字符
字符串位置方法
有两个可以从字符串中查找子字符串的方法:indexOf()和lastIndexOf(),这两个方法都是从一个字符串中搜索给定的子字符串,然后返回子字符串的位置(如果没有找到子字 符串,则返回-1) 第二个参数表示从字符串中的哪个位置开始搜索
indexOf()方法从字符串的开头向后搜索子字符串。 IndexOf()会从第二个参数指定的位置向后搜索,忽略该位置之前的所有字符
lastIndexOf()方法是从字符串的末尾向前搜索子字符串。lastIndexOf()会从指定的位置向前搜索,忽略该位置之后的所有字符。
ex: var stringValue="hello world";
alert(stringValue.indexOf("o")); //4
alert(stringValue.lastIndexOf("o")); //7
var stringValue="hello world";
alert(stringValue.indexOf("o",6)); //7 从6的位置上向后搜索
alert(stringValue.lastIndexOf("o",6); //4 从6的位置上向前搜索
在使用第二个参数的情况下,可以通过循环调用indexOf()或lastIndexOf()来找到所有匹配的子字符串
ex: var stringValue="Lorem ipsum dolor sit amet,consetetur adipisicing elit";
var positions=new Array();
var pos=0;
while(pos>-1){
positions.push(pos);
pos=stringValue.indexOf("e",pos+1);
}
alert(positions);
字符串大小写转换方法
toLocalUpperCase(); 针对特定地区的实现
toUpperCase();
toLocalLowerCase();
toLowerCase();
Math对象
min()和max()方法
Math对象还包含许多方法,用于辅助完成简单和复杂的数学计算
var max=Math.max(3,54,32,16);
alert(max); //54
var min=Math.min(3,54,32,16);
alert(min);//3
舍入方法
Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数;
Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近的整数;
Math.round()执行标准舍入(四舍五入),即它总是将数值四舍五入为最接近的整数;
random()方法
Math.random()方法返回介于0和1之间一个随机数,不包括0和1。套用下面的公式,就可以利用Math.random()从某个整数范围内随机选择一个值:
值=Math.floor(Math.random()*可能值的总数+第一个可能的值)
如果你想选择一个1到10之间的数值,可以像下面这样编写代码:
var num=Math.floor(Math.random()*10+1);
而如果想选择一个2至10之间的数值
ex: var num=Math.floor(Math.random()*9+2);
多数情况下,其实可以通过一个函数来计算可能值的总数和第一个可能的值
ex:function selectFrom(lowerValue,upperValue){
var choices=upperValue-lowerValue+1;
return Math.floor(Math.random()*choices+lowerValue);
}
var num= selectFrom(2,10);
alert(num);
ex: var colors=["red","green","blue","yellow","orange","purple"];
var color=colors[selectFrom(0,colors.length-1)];
alert(color);