『Week NO.2』
5.4 RegExp
通过RegExp类型来支持正则表达式
var exp = /pattern(模式)/flags(标志)
g:表示全局模式 即被应用于所有字符串,而非发现第一个匹配项立即停止。i:表示不区分大小写模式
m:多行模式 即到达一行文本结尾时还会继续查找下一行是否存在与模式匹配项
例:
var pattern1 = /[bc]at/i //匹配第一个“bat”或者“cat”,不区分大小写
var pattern2 = /.at/g //匹配所有以“at”结尾的3个字符组合。
var pattern3 = /\[bc\]at/i //匹配第一个“[bc]at”,不区分大小写
除了上述 字面量形式定义的正则表达式还有一种就是 使用RegExp构造函数。它接收两个参数:一个是匹配的字符串模式,另一个就是可选的标志字符串。
var pattern4 = new RegExp("[bc]at","i")
需要注意的是RegExp构造函数的
两个参数都是字符串,
不能把字面量传给RegExp构造函数。
RegExp构造函数双重转义
如:
字面量模式/\[bc\]at/在RegExp模式下 "\\[bc\\]at"
5.5 Function类型
每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
函数通常是使用函数声明语法定义:
function sum(num1,num2)
{
return num1 + num2;
}
另一种则是 函数表达式定义函数:
var sum = function(num1,num2){
return num1 + num2;
}; //注意函数末尾有一个分号
function关键字后面没有函数名,这是因为在使用函数表达式定义函数时,没有必要使用函数名——通过变量sum即可引用函数。另外,还要注意函数末尾有一个
分号,就像声明其他变量时一样。
最后一种定义函数的方式是使用 Function构造函数。Function构造函数可以接收任意数量的参数,但最后一个参数始终都被看成是函数体,而前面的参数则枚举出了新函数的参数。
var sum = Function('num1','num2','return num1 + num2'); //不推荐
--------------------------------------------------------------------------------------------------------------------------------------------------
function sum(num1,num2)
{
return num1 + num2;
}
alert(sum(10,10)); //20
var anotherSum = sum; //注意:使用不带括号的函数名是访问函数指针,而非调用函数。指向同一个函数
alert(anotherSum(10,10)); //20
sum = null;
alert(anotherSum(10,10)); //20
5.5.1函数声明与函数表达式
两者的 区别:解析器对函数声明和函数表达式并非一视同仁。解析器会 率先读取函数声明,并使其在执行任何代码之前 可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。
alert(sum(10,10));
function sum(num1,num2)
{
return num1 + num2;
}
以上代码完全可以正常运行。因为在代码开始执行之前,解析器就已经读取函数声明并将其添加到执行环境中了。如果像下面例子所示,把上面的函数声明改为变量初始化方式,就会在执行期间导致 错误:
alert(sum(10,10));
var sum = function(num1,num2)
{
return num1 + num2;
}
5.5.3作为值的函数
当然,可以从一个函数中返回另一个函数,而且这也是极为有用的一种技术。
function createSumFunction()
{
return function(num1,num2){
return num1 + num2;
};
}
var sumFunction = createSumFunction();
alert(sumFunction(5,5)); //10
5.5.4函数内部属性
在函数内部,有两个特殊的对象: arguments和this。其中,arguments是一个 类数组对象,包含着传入函数中的所有参数,而且可以使用length属性来确定传递进来多少个参数。
function sayHi()
{
alert(arguments.length); //2
alert(arguments[0] + ',' + arguments[1]); //hello,world
}
sayHi('hello','world');
函数内部的另一个特殊对象是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对象。由于在调用函数之前,this的值并不确定,因此this可能会在代码执行过程中引用不同的对象。当在全局作用域中调用sayColor()时,this引用的是全局对象 window;换句话说,对this.color求值会转换成对window.color求值,于是结果就是'red'。而当把这个函数赋给对象o并调用o.sayColor()时,this引用的是对象o,因此对this.color求值会转换成对o.color求值,结果就是'blue'。
5.5.5函数属性和方法
因为JavScript中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性: length和prototype。其中,length属性表示 函数希望接收的命名参数的个数。
function sayName(name)
{
alert(name);
}
function sayHi()
{
alert('hi');
}
alert(sayName.length); //1
alert(sayHi.length); //0
在JavaScript中最耐人寻味的就要数prototype属性了。对于引用类型而言, prototype是保存它们所有实例方法的真正所在。诸如toString()和valueOf()等方法实际上都是保存在prototype名下,只不过是通过各自对象的实例访问罢了。在创建自定义引用类型以及实现继承时,prototype属性的作用是极为重要的。(详细见第六章)
每个函数都包含两个非继承而来的方法: apply()和call()。这两个方法的用途是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。首先,apply()方法接受两个参数:一个是在其中 运行函数的作用域,另一个是 参数数组。其中,第二个参数可以是Array的实例,也可以是arguments对象。例如:
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
在上面例子中,callSum1()在执行sum()函数时传入了this作为作用域(因为是在全局作用域中调用的,所以传入的就是window对象)和arguments对象。而callSum2同样也调用了sum()函数,但它传入的则是this和一个参数数组。
call()方法与apply()方法的作用相同,它们的区别仅在于接收参数的方式不同。对于call()方法而言,第一个参数是作用域没有变化,变化的只是其余的参数都是直接传递给函数的。
function callSum2(num1,num2)
{
return sum.call(this,num1,num2);
}
alert(callSum2(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
在js中还定义了一个方法: bind().这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值
5.6基本包装类型 ( 每个包装类型都映射到同名的基本类型)
提供了3个特殊的引用类型 Boolean、Number和String
var s="sss";
var sub=s.substring(2);
s是
基本类型值却有方法?
实际上后台已经自动完成了一系列处理,当第二行访问s时,后台会完成下列处理:
1,创建一个string类型的实例
2,在实例上调用指定方法
3,销毁这个实例
实际上就相当于执行了下列过程:
var s=new String("sss");
var sub=s.substring(2);
s=null;
上面过程适用于String 、Boolean、 Number
引用类型与基本包装类型的主要 区别就是对象的生存期。使用 new操作符创建的引用类型的实例,在执行流离开当前作用域之前都 一直保存在内存中,而自动创建的 基本包装类型的对象 则只存在于一行代码的执行瞬间,然后被 立即销毁。如:
var s1 = "some text"
s1.color = "red";
alert(s1.color); //undefined
基本包装类型调用typeOf会返回“object”,而且所有的基本包装类型的对象都会被转换成布尔值true。
1.Boolean类型
Boolean类型是与布尔值对应的引用类型
基本类型与引用类型的布尔值的区别(所以不建议实例化,会造成混淆):
(1)typeof对基本类型返回“boolean”,对引用类型返回“object”
(2)instanceof检测Boolean对象返回true,检测基本类型的布尔值返回false
2.Number类型
Number是与数字值对应的引用类型
(1)创建Number对象,会调用Number构造函数,向其中传递相应的数值
var numberObject=new Number(10); //建议实例化
(2)Number类型重写了valueOf() //返回基本类型表示的数值,toLocaleString(),toString()//返回字符串形成的数值
var num=10;
alert(num.toString()); //10
alert(num.toString(2)); //1010
(3)toFixed方法
(4)toPrecision方法
(5)typeof,instanceof检测的区别
3.String类型
Stirng类型时字符串的包装类型,使用String构造函数来构建
var stringObject=new String(“hello world”);
Stirng类型的方法:
(1) 字符方法:用于访问字符串中特定字符
charAt()
charCodeAt()
(2) 字符串操作方法
concat()用于拼接字符串,一般用+代替
slice(子字符串的开始位置,结束位置的后一个位置)
substring(子字符串的开始位置,结束位置的后一个 位置)
substr(子字符串的开始位置,子字符串的字符 个数)
参数为正的情况下返回基本相同, 为负时有较大区别。
(3)字符串位置方法
indexOf(“要查找的字符","开始查找的位置") // 顺序查找
lastIndexOf() // 逆序查找
var myString="hello world";
var position=new Array();
var pos=myString.indexOf("o");
while(pos>-1){
position.push("pos");
pos=myString.indexOf("o",pos+1);
}
alert(position);
(4)trim() 删除字符串前置和后缀的空格
var myString=” hello world ”;
var newString=myString.trim();
alert(newString); //”hello world”
alert(myString); //” hello world ”创建的是字符创的副本,所以不改变原字符串
(5)字符串大小写转换
toUpperCase()
toLocaleUpperCase() //针对特定地区,在不知道代码在何处运行时使用
toLowerCase()
toLocaleLowerCase() //同上
(6)字符串模式匹配方法
match() : //使用正则表达式模式对字符串执行查找,并将包含查找的结果作为 数组返回。
使用方法:
stringObj.match(rgExp)
对其进行查找的 String 对象或字符串文字。
search():接受一个由字符串或者RegExp对象指定的正则表达式,返回字符串中第一个匹配项的 索引
replace(字符串或RegExp对象,字符串或函数) //用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
split():指定分隔符,将字符串分割成多个子字符串,并将结果放到数组中,第一个参数为分割符,第二个为数组的大小
(7)localeCompare()方法
比较两个字符串,返回-1,0,1
(8)fromCharCode():String构造函数的一个静态方法,接受一或多个字符编码,转换成字符串
alert(String.fromCharCode(104,101,108,108,111)); //”hello”
(9)HTML方法
5.7单体内置对象
1.Global对象
所有在全局作用域中定义的属性和函数都是Global对象的属性
(1)URI编码方式
对URI进行编码,以便发送给浏览器,有效的URI中不能包含某些字符,例如空格,所以要进行编码
encodeURI()
encodeURIComponent()
decodeURI()
decodeURIComponent()
(2)eval()方法
像一个ECMAScript解析器,接受要执行的ECMAScript字符串作为参数,并执行
(3)Global对象的属性
undefinded,NaN,Number,String,Boolean,Object,Function,Array,Infinity,Date,RegExp,Error等
(4)window对象
Web浏览器将Global对象作为window对象的一部分,在全局作用域中声明的所有变量和函数,就成了window对象的属性
var color="red";functin sayColor(){ alert(window.color);}window.sayColor(); //"red"
2.Math对象
(1)Math对象的属性
Math.PI //π的值
Math.SQRI2 //2的平方根
(2)min() 和max()方法
var max=Math.max(3,4,5);
alert(max);//5
var min=Math.min(3,4,5);
alert(min);//3
var values=[1,2,3,4];
var max=Math.max.apply(Math,values);
(3)
舍入方法
Math.ceil() //向上舍入
Math.floor() //向下舍入
Math.round() //标准舍入,四舍五入
(4)random()方法 //Math.random()返回0到1的随机数
从某个整数范围内随机选择一个值:
值=Math.floor(Math.Random()*可能值的总数+第一个可能的值)
Math.floor(Math.Random()*9+2); //2到10有9个数
例2到10的整数:
Math.floor(Math.Random()*9+2); //2到10有9个数
function getRandom(min,max){
var length=max-min+1;
return Math.floor(Math.Random()*length+min);
}
var result=getRandom(2,10);
alert(result);
(5)其他方法
Math.tan(x);
Math.sin(x);
Math.cos(x);