[Code 小心得]JS 篇[書本筆記篇] (持續更新中)


總是使用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)主要用途就是初始化那個新物件。

留言