函数表达式
1:函数的两种形式
1:函数声明,类似于大多数语言(c/c++/java/php)。
function fun(name, age){
var qinjie = name + age;
return qinjie;
}
2:函数表达式,创建一个函数变量并将其值赋给某个变量。这种产生的函数也称为”匿名函数”
var fun = function(name, age){
var qinjie = name + age;
return qinjie;
}
2:递归
1:直接仿照其他语言形式塑造递归。js中,函数名可被赋值更改,可能导致出错。推荐使用第二种方法
function factorial(num){
if(num > 1){
return factorial(num-1)*num
}
else{
return 1;
}
}
2:使用arguments.callee,指向正在执行的函数指针
function factorial(num){
if(num>1){
return arguments.callee(num-1)*num;
}
else{
return 1;
}
}
3:闭包
闭包,简单的说就是函数里面的函数,它的作用域不仅包含自己,还包含父函数的作用域。闭包会比其他的函数占用更多的内存。
function test(){
var name = "qinjie";
var age = 21;
var getName = function(){
alert(name);
name = "daimeng";
return name;
};
alert("name="+getName());
}
test();
2:闭包只能取得包含函数中变量的最后一个值。会导致出错
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){
return i;
};
}
return result;
}
var funcs = createFunctions();
alert(funcs);
//每次输出都是10
for (var i=0; i < funcs.length; i++){
document.write(funcs[i]() + "<br />");
}
模仿块级作用域
1:在js中,没有块级作用域的概念。在块语句中定义的变量,实际上是在函数中创建的。例如循环,判断等语句中创建的变量,会在整个函数中有效。模仿块级作用域,可以减少内存占用
//未使用块级作用域
function outputNumbers(count){
for (var i=0; i < count; i++){
alert(i);
}
var i; //再次定义变量
alert(i); //5
}
outputNumbers(5);
//使用块级作用域
function outputNumbers(count){
(function () {
for (var i=0; i < count; i++){
alert(i);
}
})();
alert(i); //出错
}
outputNumbers(5);
私有变量
1:方式一,使用构造函数模式+闭包。缺点,因为使用构造函数模式,每次创建新的实例,都会创建新的方法(浪费内存)。
function Person(name){
this.getName = function(){
return name;
};
this.setName = function (value) {
name = value;
};
}
var person = new Person("qinjie");
alert(person.getName()); //"qinjie"
person.setName("daimeng");
alert(person.getName()); //"daimeng"
2:使用原型模式+私有作用域。缺点:多个实例共用同一个方法和变量。
(function(){
var name = "";
Person = function(value){
name = value;
};
Person.prototype.getName = function(){
return name;
};
Person.prototype.setName = function (value){
name = value;
};
})();
var person1 = new Person("qinjie");
alert(person1.getName()); //"qinjie"
person1.setName("daimeng");
alert(person1.getName()); //"daimeng"
var person2 = new Person("gglinux");
alert(person1.getName()); //"gglinux"
alert(person2.getName()); //"gglinux"
3:最好的方法,使用“模块模式”。
function BaseComponent(){
}
function OtherComponent(){
}
var application = function(){
//私有的方法和变量
var components = new Array();
//初始化
components.push(new BaseComponent());
//公共的调用接口
return {
getComponentCount : function(){
return components.length;
},
registerComponent : function(component){
if (typeof component == "object"){
components.push(component);
}
}
};
}();
application.registerComponent(new OtherComponent());
alert(application.getComponentCount()); //2