Source From Here
前言 :
如果你有以下建立物件的需求 :
這些物件在建立時,具有相同的特性名稱,只不過特性值不同,其實你可以定義一個函式 :
接著如下呼叫,就可以有相同的效果 :
像
Person 這樣的函式,接在 new 之後使用時,俗稱為 建構式(Constructor),通常對從類別為基礎的語言過來的人,也會說這就像是一個類別(Class),不過這只是比擬,實際上當然與類別有所差別.
建構式 :
實際上你使用 new 運算子後接上一個函式時,相當於作這樣的動作(一部份是這樣,不過還有別的細節,之後再談):
這也說明了,為什麼使用 new 接上函式,傳回的物件會有 name 與 age,因為 Person 中,this 所參考的就是 p 所參考的物件,所以在 this 上新增特性,就相當於在 p 所參考物件上新增特性. 一個函式作為建構式使用時,基本上無需撰寫 return,如果建構式有傳回值,那傳回值就會被當作最後名稱所參考的值. 例如 :
所以要以比擬的方式來說,new 之後接上建構式,預設相當於這樣 :
每個透過 new 建構的物件,都會有個 constructor 特性,參考至當初建構它的函式. 例如 :
這可以作為物件類型的參考依據,不過要注意的是,constructor 是可以修改的! 由於透過建構式所建立的物件,所有的特性都是直接新增在物件上,也因此可以直接透過 . 運算子加以存取. 例如 :
對熟悉物件導向私有性基本觀念的人來說,可能覺得這不安全,這相當於在物件導向觀念中,每個類別成員都是公開成員的意味. JavaScript 本身並不支援物件導向公開、私用性等觀念,如果你想模擬,則可以如下 :
以上假設的是,name 不可以被設定,但可以透過 getName() 來取得,之所以會有這樣的效果,其實就是 閉包 的作用. 上例中,在物件上新增了 getName 特性,參考至一個函式,該函式形成閉包綁定了參數 name,參數也就是區域變數,並非物件上的特性,所以無法透過 . 運算子取得,因此模擬了私用性! 由於閉包綁定的是自由變數本身,所以也可以如下,在設定值(或取得值)時予以保護 :
前言 :
如果你有以下建立物件的需求 :
- var p1 = { name : 'Justin', age : 35};
- var p2 = { name : 'Momor', age : 32};
- var p3 = { name : 'Hamimi', age : 2};
- function Person(name, age) {
- this.name = name;
- this.age = age;
- }
- var p1 = new Person('Justin', 35);
- var p2 = new Person('Momor', 32);
- var p3 = new Person('Hamimi', 2);
建構式 :
實際上你使用 new 運算子後接上一個函式時,相當於作這樣的動作(一部份是這樣,不過還有別的細節,之後再談):
這也說明了,為什麼使用 new 接上函式,傳回的物件會有 name 與 age,因為 Person 中,this 所參考的就是 p 所參考的物件,所以在 this 上新增特性,就相當於在 p 所參考物件上新增特性. 一個函式作為建構式使用時,基本上無需撰寫 return,如果建構式有傳回值,那傳回值就會被當作最後名稱所參考的值. 例如 :
所以要以比擬的方式來說,new 之後接上建構式,預設相當於這樣 :
每個透過 new 建構的物件,都會有個 constructor 特性,參考至當初建構它的函式. 例如 :
這可以作為物件類型的參考依據,不過要注意的是,constructor 是可以修改的! 由於透過建構式所建立的物件,所有的特性都是直接新增在物件上,也因此可以直接透過 . 運算子加以存取. 例如 :
對熟悉物件導向私有性基本觀念的人來說,可能覺得這不安全,這相當於在物件導向觀念中,每個類別成員都是公開成員的意味. JavaScript 本身並不支援物件導向公開、私用性等觀念,如果你想模擬,則可以如下 :
以上假設的是,name 不可以被設定,但可以透過 getName() 來取得,之所以會有這樣的效果,其實就是 閉包 的作用. 上例中,在物件上新增了 getName 特性,參考至一個函式,該函式形成閉包綁定了參數 name,參數也就是區域變數,並非物件上的特性,所以無法透過 . 運算子取得,因此模擬了私用性! 由於閉包綁定的是自由變數本身,所以也可以如下,在設定值(或取得值)時予以保護 :
沒有留言:
張貼留言