五 函数基础
1 定义方法:
(1)静态方法:
function 函数名([参数列表]){ 函数体; [return [函数返回值;] }
(2)动态匿名方法:var 函数名=new Function([“虚参列表”],”函数体”);
(3)直接量方法:函数名=function([虚参列表]){函数体;}
function sum(num1,num2){ return num1 + num2; } var sum=function(num1,num2){ return num1 + num2; } var sum=new Function("num1", "num2", "return num1+num2");
Ps:使用函数表达式定义函数时,可以不用定义函数名,通过变量名可以直接引用函数。同时函数表达式的末尾记得有分号。
Ps:使用不带圆括号的函数名是访问函数指针,而非调用函数。
2 调用方法:
(1)作为函数调用
直接调用:函数名(实参列表)
在连接中调用:<a href=”javascript:函数名()”>zhii</a>
在事件中调用:事件类型=”函数名()”
递归调用:在函数体内部调用函数自身,function 函数名(){ 代码;函数名();}
(2)作为方法调用
o.m=f; o.m(); o.m(x,y) var calculator={ opera1:1, opera2:1, add:function(){ this.result=this.opera1+this.opera2; } }; calculator.add(); calculator.result;
(3)作为构造函数调用
若函数或方法调用之前带有关键字new,则为构造函数调用。如果构造函数调用在圆括号内包含一组实参列表,先计算这些参数表达式,然后传入函数内。如果构造函数没有形参,JavaScript构造函数调用的语法啊是允许省略实参列表和圆括号的。凡是没有形参的构造函数调用都可以省略圆括号。
var o=new Object(); 等价于 var o=new Object;
ps:(1)构造函数通常不用return关键字,它们通常初始化新对象,当构造函数的函数体执行完毕后,会显示返回。此时,构造函数调用表达式的计算结果就是这个新对象的值。(2)若构造函数显示return一个对象,则调用表达式的值就是这个对象。(3)若构造函数使用return语句但没有指定返回值,或返回一个原始值,此时将忽略返回值,同时使用这个新对象作为返回结果。
(4)通过它们的apply()、call()方法间接调用
function Animal() { this.name = 'Animal'; this.showName = function () { alert(this.name); } } function Cat() { this.name = 'Cat'; } var animal = new Animal(); var cat = new Cat(); //通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。 //输入结果为"Cat" animal.showName.call(cat, ','); //animal.showName.apply(cat,[]);
3 函数内部属性:
在函数内部,存在两个特殊的对象:arguments与this
[1] arguments是一个类数组对象,包含着传入函数中的所有参数,其主要用于保存函数参数。arguments对象有一个叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。
function factorial(num){ if(num <= 1){ return 1; }else{ return num * arguments.callee(num - 1); } }
[2] 函数内部的另一个对象this,其引用的是函数执行的环境对象,或者说是this值。
[3] ES5规范了另一个函数对象的属性caller,其保存着调用当前函数的函数的引用。若在全局作用域内调用当前函数,其值为null。
4 函数属性:
每个函数都包含两个属性:length、prototype。其中,length属性表示函数希望接收的命名参数的个数。prototype是保存引用类型所有实例方法的真正所在。即toString()等方法都保存在prototype上,只不过是通过各自对象的实例访问罢了。
function syName(num1,num2){ return num1 + num2; } console.log(sayName.length);//2
5 方法:
每个函数都包含两个非继承而来方法:apply()、call(),二者的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值,可以扩充函数赖以运行的作用域。
apply::(将函数作为对象的方法来调用,将参数以数组形式传递给该方法;)
call:(将函数作为对象的方法来调用,将参数传递给该方法)
toString:(返回函数的字符串表示)
ps:apply()接收两个参数,前一个是在其中运行函数的作用域,后一个是参数数组,其中后一个参数可以是Array的实例,也可以是arguments对象。而call()接收两个参数,前一个是与apply一致,后一个参数是传递给函数的参数必须逐个列举出来。
function sum(num1, num2){ return num1 + num2; } function apSum1(num1, num2){ return sum.apply(this,arguments); } function apSum2(num1, num2){ return sum.apply(this,[num1, num2]); } function callSum(num1, num2){ return sum.call(this, num1, num2); } console.log(apSum1(10,10));//20 console.log(apSum2(10,10));//20 console.log(callSum(10,10));//20 window.color="red"; var o={ color: "blue"}; function sayColor(){console.log(this.color);} sayColor();//red sayColor.call(this);//red sayColor.call(window);//red sayColor.call(o);//blue
ps: 使用call()、apply()扩充作用域的好处是对象不需要与方法有任何耦合关系。
bind():创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
window.color="red"; var o={ color: "blue"}; function sayColor(){ console.log(this.color); } var objSayColor=sayColor.bind(o); objSayColor();//blue
6 arguments对象:
存放实参的参数列表;仅能在函数体内使用,带有下标属性但并非数组,函数声明时自动初始化;其属性有length(获取函数实参的长度)、callee(返回当前正在指向的函数)、caller(返回调用当前正在执行函数的函数名)
7 函数参数:
参数类型:形参(定义函数时使用的参数; 接收调用该函数时传递的参数)、实参(调用函数时传递给函数的实际参数)
特性:参数个数没有限制,当实参个数 < 形参个数时,多余参数为undefined,当实参个数 > 形参个数时,多余实参会被忽略; 参数的数据类型没有限制; 通过arguments对象访问参数数组; 参数始终按值传递,基本类型传值,引用类型传地址
Ps:形参:函数中定义的变量; 实参:运行时的函数调用时传入的参数。
8 指针标识:
this:(指向当前操作对象)
callee:(指向参数集合所属函数)
prototype:(指向函数附带的原型对象)
constructor:(指向创建该对象的构造函数)
Ps:函数实际上是对象。每个函数都是Function类型的实例,具有属性与方法。由于函数是对象,则函数名实际上是一个指向函数对象的指针。
Ps:若函数挂载在一个对象上,作为对象的一个属性,则称其为对象的方法。当通过这个对象来调用函数时,该对象即为此次调用的上下文,即该函数的this值。
Ps:用于初始化一个新创建的对象的函数称为构造函数。
Ps:JavaScript中,函数本质上是对象,可以给其设置属性或者调用其方法。同时,可以把函数赋值给变量或者将参数传递给其他函数。
六 字符串
String类型是字符串的对象包装类型,可以使用String构造函数来创建:
var stringObj=new String(“hello”);
1 查找方法:
(1) 字符方法
charAt():(返回字符串中第n个字符; 参数超出范围,返回空字符串; 返回值为string中第n个字符的实际值)
charCodeAt():(返回字符串中第n个字符的代码; 超出范围返回NaN; 返回值为string中第n个字符的Unicode编码)
fromCharCode():(根据字符编码创建字符串; 返回由指定编码字符组成的新字符串)
var stringVal="hello world"; alert(stringVal.charAt(1));//"e" alert(stringVal.charCodeAt(1));//101 (小写e的字符编码) alert(String.fromCharCode(104,101,108,108,111));//"hello"
(2) 位置方法
indexOf(将要查找的子字符串[,开始查找的位置坐标]):(从前往后检索字符串,看其是否含有指定子串; 返回值为子串首次出现的下标或-1)
lastIndexOf(将要查找的子字符串[,开始查找的位置坐标]):(从后向前检索字符串,看其是否含有指定子串; 返回值为子串首次出现的下标或-1)
var stringVal="hello world"; alert(stringVal.indexOf("o"));//4 alert(stringVal.indexOf("o",6));//7 alert(stringVal.lastIndexOf("o"));//7 alert(stringVal.lastIndexOf("o",6));//4
(3) 匹配方法
match(要进行模式匹配的正则表达式,非正则表达式):(找到一个或多个正则表达式的匹配; 参数2将其传递给RegExp()构造函数,并转换为正则表达式对象; 返回值为存放匹配结果的数组或Null,有全局标记g的执行全局搜索,无g标记的只执行一次匹配)
search(要进行模式匹配的正则表达式,非正则表达式):(检索字符串中与正则表达式匹配的子串; 返回值为字符串中第一个与正则表达式相匹配的子串的起始位置或-1; )
replace(需要进行替换正则表达式对象或字符串,替换文本或替换函数):(替换一个与正则表达式匹配的子串;若参数1仅为字符串则只进行一次匹配替换,若替代所有子串则必须制定全局标记g; 若参数2仅为字符串则可使用特殊字符序列,如$$ => $,$& => 匹配整个模式的子字符串,$’ => 匹配的子字符串之前的子字符串,$` => 匹配的子字符串之后的子字符串,$n => 匹配第n个捕获组的子字符串,n为0-9,$nn => 匹配第nn个捕获组的子字符串,nn为01-99)
split(指定的分隔符[,指定数组的长度]):(根据指定分隔符将字符串分割成多个子串,并返回数组)
var text="cat, bat, sat, fat"; var pattern=/.at/; var matches=text.match(pattern); alert(matches.index);//0 alert(matches[0]);//"cat" alert(pattern.lastIndex);//0 var pos=text.search(/at/); alert(pos);//1 var res=text.replace("at", "ond"); alert(res);//"cond, bat, sat, fat" res=text.replace(/at/g,"ond"); alert(res);//"cond, bond, sond, fond var color="red, blue, green, yellow"; var colos1=color.split(",");//["red", "blue", "green", "yellow"] var colos2=color.split(",",2);//["red","blue"] var colos3=color.split(/[^\,]+/);//["",",",",",",",""]
2 操作方法:
(1) 拼接方法
concat():(连接字符串,返回值为连接字符串后返回的新字符串; 功能与“+”相同,原始字符串的值并未被改变; )
ps:虽然concat()方法专门用来拼接字符串的方法,但实践中更多使用+进行字符串拼接。
var stringVal="hello"; var result=stringVal.concat("world"); var result1=stringVal.concat("1","2"); console.log(result);//hello world console.log(result1);//hello12 console.log(stringVal);//hello
(2) 截取方法
根据下标截取子串:slice()、substring()
根据长度截取子串:substr()
var stringVal="hello world"; alert(stringVal.slice(3));//"lo world" alert(stringVal.substring(3));//"lo world" alert(stringVal.substr(3));//"lo world" alert(stringVal.slice(3,7));//"lo w" alert(stringVal.substring(3,7));//"lo w" alert(stringVal.substr(3,7));//"lo worl" alert(stringVal.slice(-3));//"rld" alert(stringVal.substring(-3));//"hello world" alert(stringVal.substr(-3));//"rld" alert(stringVal.slice(3,-4));//"lo w" alert(stringVal.substring(3,-4));//"hel" alert(stringVal.substr(3,-4));//" "(空字符串)
ps:当给这些函数传递负数的情况下,slice()方法会将传入的负值与字符串的长度相加;substr()方法将负的第一个参数加上字符串的长度,而负的第二个参数转换为0;substring()方法会把所有负值参数都转换为0,同时如果一正一负的话,将负的转换为0后,将较小的参数作为起始位置,较大的参数作为结束位置。
(3) 空格处理
trim() :(消除前置及后缀空格)
trimLeft():(消除前置空格)
trimRight():(消除后缀空格)
var stringVal=" hello world "; var trimStr=stringVal.trim(); alert(trimStr);//"hello world" alert(stringVal);//" hello world "
(4) 比较方法
localeCompare():(用本地特定顺序比较两个字符串; 返回值为说明比较结果的数字,负数表示原字符串<参数字符串,正数表示原字符串>参数字符串;为0表示二者相等。)
var stringVal="yellow"; alert(stringVal.localeCompare("brick"));//1 alert(stringVal.localeCompare("yellow"));//0 alert(stringVal.localeCompare("zoo"));//-1
3 编码方法:
字符串常规编码与解码:escape()、unescape()
URI字符串编码与解码:encodeURI()、decodeURI()
URI组件编码与解码:encodeURIComponent()、decodeURIComponent()
4 转换方法:
大小写转换:转为大写(toUpperCase()、toLocaleUpperCase())、转为小写(toLowerCase()、toLocaleLowerCase())
参考资料:
《JavaScript高级程序设计》、《JavaScript权威指南》