1.函数就是对象
函数可以存放变量,数组,对象
函数可以当做参数传递给其他函数
函数可以返回函数
函数可以拥有方法
2.函数的调用
调用运算符是任何一个产生函数值的表达式之后的一对圆括号。
调用一个函数将暂停当前函数的执行,传递控制权和参数给新函数,除了声明时定义的形参,每个函数接收两个附加的参数-this和arguments。
this的值取决于调用的模式:
方法调用模式:函数被保存为对象的一个属性时,称为方法。方法被调用时,this绑定到该对象。
var obj={
value:0,
increment:function(){
this.value+=1;
}
}
obj.increment();
obj.value;
函数调用模式:当一个函数并非对象的属性时,它被当作一个函数来调用,this绑定到全局对象(Window),因此不能共享外部函数对对象的访问权-语言设计的错误。当内部函数被调用时,this应该仍绑定到外部函数的this变量。
解决方案:定义一个变量并给它赋值为this
var myObj={
value: 0,
getValue: function(){
return this.value;
}
};
myObj.test=function(){
var that = this
var helper=function(){
that.value+=1;
}();
}
myObj.test();
构造器调用模式:如果一个函数前面带上new来调用,将会创建一个隐藏连接到该函数的prototype成员的新对象,this将会绑定到新对象上。
var Quo = function(string){
this.status=string;
}
Quo.prototype.get_status=function(){
return this.status;
}
var myQuo=new Quo("confused");
myQuo.get_status();
apply调用模式:apply方法让我们构建一个参数数组并用其去调用函数。该方法允许我们选择this的值,apply方法接收两个参数,第一个就是将被绑定给this的值,如果是null则为Window对象,第二个是参数列表。
var array=[3,4];
var sum=add.apply(null,array);
var Quo = function(string){
this.status=string;
}
Quo.prototype.get_status=function(){
return this.status;
}
var statusObj={
status:"OK"
};
Quo.prototype.get_status.apply(statusObj);
var myObj={
add:function(a,b){
//参数为null或#ff0000,this引用为Window, double函数的alert证明了这一点
alert(this.location.href);
return a+b;
}
}
var array=[3,4];
var sum=myObj.add.apply(null,array);
2.给类型增加方法:待续
3.闭包-能够读/写函数内部的某些变量的子函数,并将这些变量保存在内存中.
讨论闭包之前先讨论函数作用域
1)函数内的局部变量在函数外部无法访问。
function f(){
var n=1;
}
alert(n);//error
2)内部函数可以访问外部函数的局部变量。
function f(){
var n=1;
function inner(){
alert(n);
}
}
因此只要将inner作为返回值,就可以在f外部读取它的内部变量了。
function f(){
var n=1;
function inner(){
alert(n);
}
return inner;
}
f()();
闭包就是将函数内部和函数外部连接起来的一座桥梁。如果把父函数当作对象使用,把闭包当作它的公共函数,把内部变量当作它的私有属性。
理解内部函数能访问外部函数的实际变量而无须复制:
var add_handles=function(nodes){
for(var i=0;i<nodes.length;i++){
nodes[i].onclick=function(e){
alert(i);
}
}
}
var add_handles=function(nodes){
for(var i=0;i<nodes.length;i++){
nodes[i].onclick=function(i){
return function(e){
alert(e);
}
}(i);
}
}
闭包用途:
1)读取函数内部的局部变量
2)将变量的值始终保存在内存中,因为f是inner的父函数,而inner被赋给了一个全局变量,导致inner始终在内存中,而inner的存在依赖于f,因此f也始终在内存中,不会在调用结束后被垃圾回收机制回收。
3)通过保护变量的安全实现JS私有属性和私有方法(不能被外部访问)
缺点:闭包使得函数中的变量都被保存在内存中,内存消耗很大,不能滥用闭包。
4.模块
一个定义了私有变量和函数的函数,利用闭包创建可以访问私有变量和函数的特权函数,然后返回这个特权函数。
提供接口却隐藏状态与实现的函数或对象。摒弃了全局变量。