函數表達式
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