讀書筆記-JavaScript技術手冊4: 物件基本語法


基本語法

  • delete:刪除物件屬性
  • in:確認物件是否擁有某屬性 property in object
  • 確認屬性值是否為 undefined→ 應用:option object,可避免屬性值為期他的 Falsy family (0、''、false、null):

      function has(obj, name){
          return typeof obj[name] !== 'undefined';
      }
    
      let obj = {x: undefined, y: 0};
      console.log(has(obj, 'x'));   // false
      console.log(has(obj, 'y'));   // true
      console.log(has(obj, 'x'));   // false
    

this

  1. 最基本用法:參考至 . operator 左邊的物件

    function forEach(callback){
      for(let i = 0; i < this.length; ++i){
          callback(this[i]);
      }
    }
    
    let arrayLikeObj = {
      '0': 100,
      '1': 200,
      '2': 300,
      length: 3,
      forEach: forEach
    }
    obj.forEach(function(elem){
      console.log(elem);
    });
    
  2. this 參考對象其實會以呼叫方式而定,並非以是否附屬於某個物件而定(參考 call()apply()bind() 用法)

call(), apply(), bind()

call(), apply()

  • 繼承自 Function,可綁定 this 參考的對象

      // call(), apply()
      function add(num1, num2){
          return this.num + num1 + num2;
      }
    
      let o1 = {num: 10};
      let o2 = {num: 100}
      let args = [20, 30];
      console.log(add.call(o1, 10, 20));   // 40
      console.log(add.apply(o2, args));    // 150
    

bind()

  • 回傳新函式並固定 this 參考對象

      function forEach(callback){
          for(let i = 0; i < this.length; ++i){
              callback(this[i]);
          }
      }
    
      let obj = {
          '0': 100,
          '1': 200,
          '2': 300,
          length: 3
      };
    
      let f = forEach.bind(obj);
      f(function(elem){
          console.log(elem);
      });
    
  • this 指定為 undefined:Partial function 效果

      function plus(a, b){
           return a + b;
      }
    
      let addFive = plus.bind(undefined, 5);
      console.log(addFive(5));    // 10
      console.log(addFive(10));   // 15
    

對於一個單純是函式且不需使用到this的情況下,建議將this設為undefined

箭頭函式 & this

  • arrow function 的 this 由自己所在的環境(lexical environment)決定
  • arrow function 的 this 一旦綁定就不能變更

      // Node.js
      this.x = 1;   // this 是全域物件
      function foo1(){
          return this.x;
      }
    
      let o1 = {x: 10, foo1:foo1};
      o1.foo1();   // 10
    
      // 模擬箭頭函式
      let self = this;
      self.x = 1;
    
      function foo2(){
          return self.x;
      }
    
      let o2 = {x: 10, foo2: foo2};
      o2.foo2();   // 1
    

全域物件

  • 嚴格模式的全域 thisundefined
    • 非嚴格模式則參考至全域物件
  • 取得全域物件
      Function('return this')()   // Function建立函式必須用字串指定函式內容
    
  • <globalThis>

ES6 Sugar syntax for object

object literal

  • function

      // ES6以前
      var obj1 = {
          '0': 100,
          '1': 200,
          '2': 300,
          length: 3,
          forEach: function(callback){
              for(var i = 0; i < this.length; ++i){
                  callback(this[i]);
              }
          }
      }
    
      // ES6
      let obj2 = {
          '0': 100,
          '1': 200,
          '2': 300,
          length: 3,
          forEach(callback){   // 省略 function
              for(let i = 0; i < this.length; ++i){
                  callback(this[i]);
              }
          }
      }
    
  • 運算結果作為屬性名稱

      // ES6以前
      let prefix = 'doSome';
      let n = 1;
      let o = {};
      o[prefix + n]: function(){};
    
      // ES6
      let o1 = { [prefix + n]: function(){} };
      let o2 = { [prefix + n](){} };
    

settet-getter

  • set 設值方法:object.property = value 會呼叫設值方法
  • get 取值方法:object.property 會呼叫此方法取值
  • 以下範例將 setget 封裝在 function 內,無法以 object() 存取 obj_privates

      function object(){
          let obj_privates = {};
          let obj = {
              set name(value){
                  obj_privates.name = value.trim();
              }.
              get name(){
                  return obj_privates.name.toUpperCase();
              }
          };
          return obj;
      }
    
      let obj = object();
      obj.name = '    Justin        ';
      console.log(`[${obj.name}]`);   // [JUSTIN]
    

Destructuring 解構

  • 只要是可迭代的物件(i.e., 可傳回迭代器)都可以解構
  • array

      // ES6以前
      var points = [80, 90, 99];
      var x = point[0];
      var y = point[1];
      var z = point[2];
    
      // ES6
      let point = [80, 90, 99];
      let [x, y, z] = scores;
    
      // 可迭代物件(會傳回迭代器)
      let [x, y, z] = 'XYZ';
    
      // Partial destructuring
      let [x, , y, , z] = [1, 2, 3, 4, 5];
      console.log(x);   // 1
      console.log(y);   // 3
      console.log(z);   // 5
    
  • object

      // ex1.
      let point = {x: 10, y: 20};
      let {x, y, z = 30} = point;   // 指定z有預設值, 否則z為undefined
    
      // ex2.
      function foo({x, y}){
           console.log(x, y);
      }
      foo({x: 10, y: 20});  // 10 20
    
      // ex3. Rest
      let {x, y, ...z} = {x: 1, y: 2, a: 3, b: 4};
      console.log(x);   // 1
      console.log(y);   // 2
      console.log(z);   // {a: 3, b: 4}
    
      // ex4. Spread
      z = {a: 9, b: 10}
      let n = {x, y, ...z};
      console.log(n);   // {x: 1, y: 2, a: 9, b: 10}
    
  • 變數置換

      let x = 10, y = 20;
      [x, y] = [y, x];
      console.log(x);   // 20
      console.log(y);   // 10
    
  • 用解構+遞迴執行sum運算範例

      // ex1.
      function sum1(numbers){
          let [head, ...rest] = numbers;
          if(head){
              return head + sum1(tail);
          }else{
              return 0;
          }
      }
    
      console.log(sum1([1, 2, 3, 4, 5]));   // 15
    
      // ex2.
      function sum2([head, ...tail]){
          return head ? head + sum2(tail) : 0;
      }
      console.log(sum2([1, 2, 3, 4, 5]));   // 15
    

...operator

  • Rest 餘集

      let lt = [10, 9, 8, 7, 6];
      let [head, ...tail] = lt;
      console.log(head);   // 10
      console.log(tail);   // [9, 8, 7, 6]
    
      let [, ...tail] = [1, 2, 3, 4, 5];
      console.log(tail);   // [2, 3, 4, 5];
    
  • Spread

      // ex1.
      let arr = [1, 2, 3];
      let arr2 = [...arr, 4, 5];
      console.log(arr2);   // [1, 2, 3, 4, 5];
    
      // ex2.
      function plus(a, b){
          return a + b;
      }
      console.log(plus(...[1, 2]));   // 3
    
#javascript #book #note






你可能感興趣的文章

MTR04_0729

MTR04_0729

物件屬性使用getter setter 與映射物件

物件屬性使用getter setter 與映射物件

模組化與 library

模組化與 library






留言討論