您的位置:首页 > Web前端 > JavaScript

JS高级程序设计7-函数表达式

2015-07-15 20:12 686 查看
函数声明提升的概念(相对于函数表达式)(176):

//不要这样做(函数体内是声明函数)(因为函数相对于表达式是提升的,会出现类似于函数重载的现象,zhezhong 语法是无效的)
if(condition){
function sayHi(){
alert('hi');
}
}else{
function sayHi(){
alert('Yo');
}
}

//可以这样做(函数体内是函数表达式)
var sayHi;
if(condition){
sayHi=function(){
alert('hi!');
}
}else{
sayHi=function(){
alert('Yo!');
}
}


递归(递归函数是在一个函数通过名字调用自身的情况下构成的)(P177)

function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}


闭包(指有权访问另一个函数作用域中的变量的函数,在一个函数中创建另一个函数就是最常见的闭包)(P178)

举个例子

function createComparisonFunction(propertyName){
return function(object1,object2){
var value1=object1[propertyName];
var value1=object1[propertyName];
if(value1<value2){
return -1;
}else if(value1>value2){
return 1;
}else{
return 0;
}
}
}
(注:一般在函数执行完毕之后,局部活动对象就会被销毁,内存中仅保存全局作用域,但闭包的情况有所不同)


关于this对象

全局函数中,this等于window,匿名函数的执行坏境具有全局性,因此其this对象通常指向window
var name="The Window";
var object={
name:"My Object",
getNameFunc:function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()); //"The Window"
可以修改this的指向
var name="The Window";
var object={
name:"My Object",
getNameFunc:function(){
var that=this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()); //"My Object"


内存泄露

function assignHandler(){
var element=document.getElementById("someElement");
element.onclick=function(){
alert(element.id);
};
}
//创建了一个作为element元素时间处理程序的闭包,而这个闭包又创建了一个循环引用,其中匿名函数保存了对assignHandler()的活动对象的引用,因此会导致无法减少element的引用数,所以只要匿名函数存在,element的引用数就至少为1,所以其内存就永远收不回来

//解决方法
function assignHandler(){
var element=document.getElementById("someElement");
var id=element.id;
element.onclick=function(){
alert(id);
};
element=null;
}


模拟块级作用域(P184)

JS没有块级作用域

//JS没有块级作用域的概念,这意味着在块语句中定义的变量,实际上是包含函数中而非语句中创建的
function outputNumbers(count){
for(var i=0;i<count;i++){
alert(i);//1,2,3,4,5,6,7
}
//没有影响,不会重置变量(多次声明同一个变量,JS会对后续的声明视而不见,但它会执行后续声明中变量的初始化)
var i;
alert(i);//8
}
outputNumbers(8);


匿名函数解决没有块级作用域的问题

(function(){
//这里是块级作用域
})();
//上面的代码不但定义了一个匿名函数,而且在定义的同时也调用了它,上面相当于为块级作用域创建了一个私有作用域(块级作用域就是私有作用域)
function outputNumbers(count){
(function(){
for(var i=0;i<count;i++){
alert(i);
}
})();
alert(i); //不会弹出9!
}
outputNumbers(9);
(这种设置块级作用域的技术经常在全局作用域中被用在函数外部,这是为了限制过多的函数和变量成为全局作用域的一部分,因为全局作用于中的变量和函数太多,容易导致命名冲突)


私有变量(P186)

特权方法

A:构造函数中定义特权方法
function MyObject(){
//私有变量和私有函数
var privateVariable=10;
function privateFunction(){
return false;
}
//特权方法(有权访问私有变量和私有函数的公用方法)
this.publicMethod=function(){
privateVariable++;
return privateFunction();
};
}

B:私有作用域中创建特权方法
(function(){
//私有变量和私有函数
var privateVariable=10;
function privateFunction(){
return false;
}

//构造函数
MyObject=function(){
};

//共有(特权)方法(特权方法是在原型上定义的)
Myobject.prototype.publicMethod=function(){
privateVariable++;
return privateFunction();
}
})();


模块模式(P189)

//这种模式在需要对单例(里面的对象?)进行某些初始化,同时有需要维护其私有变量时是非常有用的
var singleton=function(){
//私有变量和私有函数
var privateVariable=10;
function privateFunction(){
return false;
}
//特权(共有)方法和属性
return{
publiceProperty:true,
publicMethod:function(){
privatevariable++;
return privateFunction(){};
}
};
}();

增强的模块模式
var singleton=function(){
//私有变量和私有函数
var privateVariable=10;
function privateFunction(){
return false;
}
//创建对象
var object=new customType();
//添加特权(公共)属性和方法
object.publicProperty=true;
object.publicMethod=function(){
privateVariable++;
return privateFunction();
};
//返回这个对象
return object;
}();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: