[JavaScript] 物件導向寫法

程式語言:JavaScript

簡介:如何宣告和應用

  1. function Obj(y)
  2. {
  3. // public 可被繼承
  4. this.x = 10; // 第一種寫法
  5. this["y"] = y; // 第二種寫法
  6. this.z = function() // 新增 z function
  7. {
  8. console.log(this.x)
  9. console.log(this.y)
  10. console.log(a) // >> 3
  11. return this.x;
  12. }
  13. // private 只可見於 function 內,不可被繼承,外部無法使用
  14. var a = 3;
  15. var b = function()
  16. {
  17. console.log(a)
  18. return a;
  19. }
  20. }
  21. Obj.xx = 10; // 第三種寫法
  22. Obj.["yy"] = "yy"; // 第四種寫法
  23.  
  24. var obj = new Obj("y")
  25. console.log(obj.a) // >> undefined
  26. obj.z() // >> 10, 'y', 3

同樣名字的變數,子物件會覆蓋母物件,但若是 private 的,則會維持
呼叫時,尋找的方式為 子 -> 母 -> 祖 -> ...,直到找不到則回傳 undefined
  1. function Inherit(x, y, t) // inherit from Obj
  2. {
  3. this.prototype = Obj; // 無法使用 new Obj(y)
  4. this.prototype(y); //初始化 Obj
  5.  
  6. this.x = 100; // 覆蓋母物件 Obj 的 x
  7. this.t = t;
  8. a = 5 // 不會更改母物件 Obj 的 a
  9. }
  10. // Inherit.prototype = new Obj(y); // 在外部可使用
  11.  
  12. var inherit = new Inherit(1, "z", 30)
  13. // z() 原為 >> 10, 'y', 3
  14. inherit.z() // >> '100', 'z', 3 // a 仍然為 3
  15. inherit.prototype.all = 3 // Inherit 加入 all 變數,原型已被更改
  16. inherit.only = 3 // inherit 加入 only 變數,原型未更改

prototype

prototype 是個物件
檢查是否存在屬性的 hasOwnProperty,也是在 prototype 中
故所有物件皆有此 function
  1. var prototypeType = typeof Object.prototype
  2. console.log(prototypeType); // >> object
  3.  
  4. var hasOwn = Object.prototype.hasOwnProperty("hasOwnProperty");
  5. console.log(hasOwn); // >> true

This 討論

this 的決定,依誰呼叫為主
  • 物件.函式()   => 函式內的 this 指向該物件
  • New 物件      => 建立時 this 指向該物件
  • 函式()            => 函式內的 this 指向全域物件,也就是 window
  1. function A()
  2. {
  3. this.b = 'a'
  4. console.log(this)
  5. }
  6. A() // >> window
  7. a = new A() // >> Object { b: "a" }

簡單範例:
因 foo() 前,無調用物件,故為 window
  1. var A = {
  2. f: function ()
  3. {
  4. console.log(this); // >> Object { f: A.f() }
  5. var foo = function ()
  6. {
  7. console.log(this);
  8. }
  9. foo(); // >> window
  10. }
  11. };
  12. A.f();
  13. // Output
  14. // >> Object { f: A.f() }
  15. // >> window

複雜範例:
  1. var x = 'window';
  2. var A = {
  3. x:'A',
  4. f: function(){ console.log(this.x); }
  5. };
  6.  
  7. A.f(); // >> A
  8.  
  9. var fOut = A.f;
  10. fOut(); // >> window
  11.  
  12. var B = {
  13. x:'B',
  14. f : A.f
  15. }
  16.  
  17. B.f(); // >> B

若無法確定 this,建議直接指定,可用 call or apply
兩者差異只在傳入的參數方式不同
//函式的 this 指向 B物件(若 B物件為 null,則指向全域物件) 
(A物件.)函式.call(B物件,參數1,參數2,參數3, ......);

//函式的 this 指向 B物件(若 B物件為 null,則指向全域物件) 
(A物件.)函式.apply(B物件,[參數1,參數2,參數3, ......]); 

留言