1.函数的4种调用方式
2.函数中this的意义
3.明确构造函数对象的过程
4.学会使用上下文调用函数
一、函数调用方式
1.先声明后调用
function func(){alert("Hello World")}
func();
2.使用表达式定义函数,然后调用
var func=function(){alert("Hello World")}
func();
二、方法调用,将赋值给一个对象的成员以后,就不再称为函数,而应该叫做方法。
var func=function(){alert("Hello World")}
var o={}
o.fn=func;//这里不要加圆括号
o.fn();
此时o.fn是方法,不是函数。实际上fn的方法体跟fun是一模一样的,但是有个微妙的不同。
var func=function(){alert("Hello World")};
var o={};
o.fn=func;
alert(o.fn===func);//true
func(); //[object Window]
o.fn(); //[object object]
可见,两个函数是相同的,但是调用时不一样的,func调用,返回的是[object Window],而o.fn返回的是[object Object]
三、构造器调用,语法就是在函数调用前面加上一个new字
var Person=function(){
this.name="leilei";
this.sayHello=function(){alert("你好,这里是"+this.name);}
}
var p=new Person(); //调用构造器,创建对象
p.sayHello(); //使用对象
上述代码首先创建了一个构造函数Person,然后使用构造函数创建对象p.这里使用了new语法。然后在使用对象调用sayHello()方法,这个使用构造函数创建对象的案例比较简单。此时this指向的是对象本身。函数作为构造器还有几个变化,分别为:
1.所有需要由对象使用的属性,必须使用this引导;
2.函数的return语句意义被改写,如果返回非对象,就返回this;
构造器中的this:
分析以下代码:
var Person=function(){
this.name="程序员";
}
var p=new Person();
这里首先定义了函数Person,下面分析一下整个执行:
a)程序在执行到这一句的时候,不会执行函数体,因此JavaScript的解释器并不知道这个函数的内容;
b)接下来执行new关键字,创建对象,解释器开辟内存,得到对象的引用,将新对象的引用交给函数。
c)紧接着执行函数,将传过来的对象引用交给this。也就是说,在构造方法中,this是刚刚被new创建出来的对象。
d)然后为this添加成员,也就是为对象添加成员。
e)最后函数结束,返回this,将this交给左边的变量。
分析过构造函数的执行后,可以得到,构造函数中的this就是当前对象。
构造器中的return
在构造函数中return的意义发生了变化,首先如果在构造函数中,返回的是一个对象,那么就保留原意,如果返回的是非对象,比如数字,布尔和字符串,那么就返回this,如果没有return,也返回this.
例如:
var ctr=function(){
this.name="xuanxuan";
return{
name:"leilei";
}; //返回一个对象的return
}
var p=new ctr(); //创建对象
alert(p.name); //访问name属性
执行结果是"leilei",因为构造方法中返回的是一个对象,那么保留return的意义,返回内容为return后面的对象
换一个例子:
var ctr=function(){
this.name="xuanxuan";
return "leilei";
};
var p=new ctr();
alert(p);
alert(p.name);
返回结果,先打印[object Object],然后打印“xuanxuan”,因为这里return的是一个字符串,属于基本类型,那么这里的return语句无效,返回的是this对象,因此第一个打印的是[object Object],而第二个不会打印undefined.
四、apply调用模式
函数作为对象还有apply、call方法可以使用。
apply模式既可以像函数一样使用,也可以像方法一样使用。语法:函数名.apply(对象,参数数组)
var func1=function(){
this.name="leilei";
};
//定义方法
func1.apply(null);
alert(name);
//这里的name加载到全局对象window中,相当于函数调用
var func2=function(){
this.name="leilei";
};
var o={};
func2.apply(o);
alert(o.name)//这里的name传入对象o中,相当于方法调用
这里的参数是方法本身所带的参数,但是需要用数组的形式存储
举例:
var arr1 = [1,2,3,[4,5],[6,7,8]];
var arr2 = arr1.concat.apply([], arr1);
call模式与apply模式最大的不同在于call中的参数不用数组
举例:
var func=function(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}
var o={}
var p1=func.apply(o,["leilei",2,"女"]);
var p2=func.call(o,"leilei",2,"女");
上述代码,p1,p2结果是一样的.
实际上,使用apply模式和call模式,可以任意的操作控制this的意义,在函数js的设计模式中广泛使用。
五、综合举例
有一个div,id为dv,鼠标移到上面去高度增大2倍,鼠标离开恢复:
var dv=document.getElementById("dv");
var height=parseInt(dv.style.height || dv.offsetHeight);
var intervalId;
dv.onmouseover = function(){
clearInterval(intervalId);
var toHeight=height*2;
var that = this;
intervalId = setInterval(function(){
var height=parseInt(dv.style.height || dv.offsetHeight);
var h=Math.ceil(Math.abs(height-toHeight)/10);
if(h>0){
that.style.height = (height+h) + "px";
}
else{clearInterval(intervalId)}
},20)
}
dv.onmouseout = function(){
clearInterval(intervalId);
var toHeight=height;
var that=this;
intervalId=setInterval(function(){
var height=parseInt(dv.style.height || dv.offsetHeight)
var h=Math.ceil(Math.abs(height-toHeight)/10)
if(h>0){
that.style.height = (height-h) + "px";
}
else{clearInterval(intervalId)}
},20)
}