總是使用var 來宣告 區域變數
可考慮使用lint 工具協助 找出未繫結的變數(unbound variables)
避免使用with 述句
需要重覆存取物件時,盡量用簡短名稱
明確使用 區域變數 (Local variables)繫結到物件的特性(object properties)而非透過with述句隱含地繫結它們。
function makeSandwith(){
var magicIngredient = "peanut butter";
function make(filling){
return magicIngredient + " and " + filling;
}
return make("jelly"); //"peanut butter and jelly"
}
makeSandwith();
可注意到 內層make function 參考到 magicIngredient,一個定義在外層makeSandwich 涵式的變數
另外 即時是在外層涵式 回傳 (return) 之後,內層涵式也能夠參考定義在那些外層涵式中的變數! 因為 JavaScript 的 function 是 第一級物件 ( first-class objects) 。這也意味著 能夠回傳一個內層涵式,以供之後呼叫:
function sandwichMaker(){
var magicIngredient = "peanut butter";
function make(filling){
return magicIngredient + " and " + filling;
}
return make;
}
var f = makeSandwith();
f("jelly"); // "peanut butter and jelly"
f("bananas"); // "peanut butter and bananas"
f("marshmallows"); // "peanut butter and marshmallows"
=============================================================================================
function sandwichMaker(magicIngredient){
function make(filling){
return magicIngredient + " and " + filling;
}
return make;
}
var hamAnd = sandwichMaker("ham");
hamAnd("cheese"); // "ham and cheese"
hamAnd("mustard"); // "ham and mustard"
var turkeyAnd = sandwichMaker("turkey");
turkeyAnd("Swiss"); // "turkey and Swiss"
turkeyAnd("Provolone"); // "turkey and Provolone"
2014/04/05 update
小心 Block-Local 函式宣告造成不可移植的狀況
舉例如下
function f() { return "global"; }
function test(x){
function f(){ return "local"; }
var result = [];
if(x){
result.push(f());
}
result.push(f());
return result;
}
程序 (procedures) 方法(methods) 建構式(constructors) 類別(classes) 模組(modules) 情境或是上下文(context)
函式呼叫 方法呼叫 建構式呼叫 之間的差異
一般物件導向程式設計 (object-oriented programming)很可能習慣讓人覺得 函式 方法 與類別的建構式 當作是三種不同東西,然而在JS當中,這只是函式 這單一個程式語言構件(construct) 的三種不同的使用模式。
最簡單常見 函式呼叫(function call)
ex:
function hello(username){
return "hello", "+ username";
}
hello("Keyser Soze"); //"hello, Keyser Soze"
JS中的方法 不過剛好是身為函式的物件特性(object properties)
var obj = {
hello: function(){
return "hello, " + this.username;
},
username: "Hans Gruber"
};
obj.hello(); // "hello, Hans Gruber"
接著可以在這樣用
var obj2 = {
hello: obj.hello,
username: "Boo Radley"
};
obj2.hello(); // "hello, Boo Radley"
在一個物件上呼叫一個方法,就會在那個物件上查找那個方法,然後使用該物件作為方法的接收者。
方法是在一個特定物件上呼叫的函式,沒有理由一個普通的函式不譨提及this:
function hello(){
return "hello, " + this.username;
}
但是
var obj1 = {
hello: hello,
username: "Gordon Gekko"
};
obj1.hello(); // "hello, Gordon Gekko"
var obj2 = {
hello: hello,
username: "Biff Tannen"
};
obj2.hello(); // "hello, Biff Tannen"
把一個用到this 的函式當作函式來呼叫,而非當成方法來呼叫,是沒有用的。
hello(); // "hello, undefined"
函式 第三種用途 當作建構式 (constructors)。如同方法和一般的函式。建構式也是用function 來定義:
function User(name, passwordHash){
this.name = name;
this.passwordHash = passwordHash;
}
使用new 運算子 來調用Uer 就會把它視為一個建構式:
var u = new User("qwer", "wqo345543623eih;jewfj98490634er");
u.name; // "qwer"
不同於 函式呼叫或是方法呼叫,一個建構式呼叫會以一個全新物件當作this的值。並且隱含地回傳這個新物件當作它的呼叫結果。
這種建構函式(onstructor function)主要用途就是初始化那個新物件。
留言