标签:
函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
一、定义函数的方法:
1.函数声明
function sum(num1,num2){}
2.函数表达式
var sum=function(num1,num2){}
使用函数表达式定义时,没有必要使用函数名,但也可以是var sum=function ab(num1,num2){}
使用不带圆括号的函数名是访问函数指针,而非调用函数。
3.区别
解析器会率先读取函数声明,并使其在执行任何代码之前可用;至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。
二、函数没有重载
JS中函数没有重载,在创建第二个函数时,实际上覆盖了第一个函数。
三、作为值得函数
函数本身就是变量,所以函数也可以作为值来使用。可以像传递参数一样把一个函数传递给另一个函数,而且也可以将一个函数作为另一个函数的结果返回。
四、函数内部属性
1.arguments
在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。arguments对象和数组类似,因此可以通过方括号访问,length确定传递进来的参数个数。arguments[0]
另外arguments的值永远与对应命名参数的值保持同步。
function doAdd(num1,num2){
arguments[1]=10;
alert(arguments[0]+num2);//num2每次都被重写为10
}
这个对象还有一个属性callee,该属性是一个指针,指向拥有这个arguments对象的函数。
function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
2.另一个函数对象的属性caller
这个属性保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值为null。
function outer(){
inner();
}
function inner(){
alert(inner.caller);//弹出调用inner的函数的引用,也就是outer,因此会输出function outer(){inner();}
}
为了实现更松的耦合,可以这样调用
function inner(){
alert(arguments.callee.caller);
}
五、函数的属性和方法
每个函数都包含两个属性length和prototype; length属性表示函数希望接受的命名参数的个数。
function sayName(num1,num2){}
alert(sayName.length)//2
prototype是保存函数所有实例方法的真正所在。不可枚举,无法使用for-in发现。
每个函数都包含两个非继承而来的方法:apply()和call()
用途:在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
扩充函数赖以运行的作用域。
1.apply()
接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。第二个参数可以是Array的实例,也可以是arguments对象。
2.call()
作用同apply,区别仅在于接收参数的方式不同。第一个参数相同,第二个参数是直接传递给函数,也就是说传递给函数的参数必须逐个列举出来。
3.bind()
其this值会被指定给传给bind()函数的值。
window.color=‘red‘;
var o={color:‘blue‘};
var b={color:‘yellow‘};
function sayColor(){
alert(this.color);
}
var osaycolor=sayColor.bind(o);
var bsaycolor=sayColor.bind(b);
osaycolor()//‘blue‘
bsaycolor()//‘yellow‘
4.toLocalString() toString() valueOf()
始终返回函数的代码。
六、理解apply() call()
call和apply可以用来重新定义函数的执行环境,也就是this的指向。通过一个操作DOM的例子来理解。
function changeStyle(attr, value){
this.style[attr] = value;
}
var box = document.getElementById(‘box‘);
window.changeStyle.call(box, "height", "200px");
call中的第一个参数用于指定将要调用此函数的对象,在这里,changeStyle函数将被box对象调用,this指向了box对象,如果不用call的话,程序报错,因为window对象中没有style属性。
apply的用法:
window.changeStyle.apply(box, [‘height‘, ‘200px‘]);
function add(a,b)
{
alert(a+b);
}
function sub(a,b)
{
alert(a-b);
}
add.call(sub,3,1); // 4
2.
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来使用了。
animal.showName.call(cat,","); //Cat
//animal.showName.apply(cat,[]); //Cat
3.实现继承
function Animal(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
this.hi=function(){// 注意这里必须是this引用才能继承,否则cat.hi()时,会报错,hi不是一个函数
alert("hello "+this.name);
}
}
function Cat(name){
Animal.call(this, name);
}
var cat = new Cat("Black Cat");
cat.showName();//Black Cat
cat.hi();//hello Black Cat
4.多重继承
function Class10(){
this.showSub = function(a,b){
alert(a-b);
}
}
function Class11(){
this.showAdd = function(a,b){
alert(a+b);
}
}
function Class2(){
Class10.call(this);
Class11.call(this);
}
var c2=new Class2();
c2.showSub(10,3)//7
c2.showAdd(10,3)//13
标签:
原文地址:http://www.cnblogs.com/YangqinCao/p/5411758.html