(80)Wangdao.com第十六天_JavaScript Object 對象的相關方法

Object 對象的相關方法數組

  • Object.getPrototypeOf()
    • 返回參數對象的原型。
    • 這是獲取某對象的原型對象的標準方法。
      • var F = function () {};
        var f = new F();
        Object.getPrototypeOf(f) === F.prototype    // true

         

    • 幾種特殊對象的原型
      • // 空對象的原型是 Object.prototype
        Object.getPrototypeOf({}) === Object.prototype    // true
        
        // Object.prototype 的原型是 null
        Object.getPrototypeOf(Object.prototype) === null    // true
        
        // 函數的原型是 Function.prototype
        function f() {}
        Object.getPrototypeOf(f) === Function.prototype    // true

 

  • Object.setPrototypeOf()
    • 從新指定 某對象 的原型對象,返回 某對象。
    • 第一參數是 某對象
    • 第二參數是 新的原型對象
      • var a = {};
        var b = {x: 1};
        Object.setPrototypeOf(a, b);
        
        Object.getPrototypeOf(a) === b    // true
        a.x    // 1

        將對象 a 的原型,設置爲對象 b,所以 a 能夠共享 b 的屬性瀏覽器

    • 模擬 new 建立實例
      • var F = function () {
            this.foo = 'bar';
        };
        
        
        
        var f = new F();
        
        // 等同於
        var f = Object.setPrototypeOf({}, F.prototype);    // 將一個空對象的原型設爲構造函數的prototype屬性
        F.call(f);    // 將構造函數內部的this綁定這個空對象,而後執行構造函數,使得定義在this上面的方法和屬性(上例是this.foo),都轉移到這個空對象上

 

  • Object.create()
    • 不少時候,只能拿到一個實例對象,它可能根本不是由構建函數生成的
    • Object.create() 接收一個實例對象,以它爲原型,再建立並返回一個實例對象。
      • // 原型對象
        var A = {
            print: function () {
                console.log('hello');
            }
        };
        
        // 實例對象
        var B = Object.create(A);
        
        Object.getPrototypeOf(B) === A    // true
        B.print()    // hello
        B.print === A.print    // true

        以 A 對象爲原型,生成了 B 對象。B 繼承了 A 的全部屬性和方法函數

    • 若是想要生成一個不繼承任何屬性(好比沒有 toString() 和 valueOf() 方法)的對象,能夠將Object.create() 的參數設爲null
    • 注意: 參數不能爲空,或者不是對象,不然會報錯。能夠是 null
    • 生成的新對象,動態繼承了原型
      • 意味着在原型上添加或修改任何方法,會馬上反映在新對象之上
    • 還能夠接受第二個參數。該參數是一個屬性描述對象,它所描述的對象屬性,會添加到實例對象,做爲該對象自身的屬性
      • var obj = Object.create({}, {
            p1: {
                value: 123,
                enumerable: true,
                configurable: true,
                writable: true,
            },
            p2: {
                value: 'abc',
                enumerable: true,
                configurable: true,
                writable: true,
            }
        });
        
        // 等同於
        var obj = Object.create({});
        obj.p1 = 123;
        obj.p2 = 'abc';

         

    • Object.create() 方法生成的對象,繼承了它的原型對象的構造函數
      • function A() {}
        var a = new A();
        var b = Object.create(a);
        
        b.constructor === A    // true
        b instanceof A    // true

        上面代碼中,b 對象的原型是 a 對象,所以繼承了 a 對象的構造函數this

 

  • Object.prototype.isPrototypeOf()
    • 用來判斷該對象是否爲某對象的原型
      • var o1 = {};
        var o2 = Object.create(o1);
        var o3 = Object.create(o2);
        
        o2.isPrototypeOf(o3);    // true
        o1.isPrototypeOf(o3);    // true

         

    • 只要實例對象處在參數對象的原型鏈上,isPrototypeOf() 方法都返回 true
    • 因爲Object.prototype處於原型鏈的最頂端,因此對各類實例都返回true,只有直接繼承自 null 的對象除外

 

  • Object.prototype.__proto__ Object對象的 實例對象的 隱式原型對象
    • 根據語言標準,__proto__屬性只有瀏覽器才須要部署,其餘環境能夠沒有這個屬性
    • 它先後的兩根下劃線,代表它本質是一個內部屬性,不該該對使用者暴露
    • 應該儘可能少用這個屬性,而是用 Object.getPrototypeof() 和 Object.setPrototypeOf(),進行原型對象的讀寫操做
    • __proto__ 屬性指向當前對象的原型對象,即構造函數的 prototype 屬性

 

  • 獲取原型對象的方法的比較
    • 獲取實例對象 obj 的原型對象,有三種方法
      • obj.__proto__    只有瀏覽器才須要部署,其餘環境能夠不部署
      • obj.constructor.prototype    在手動改變原型對象時,可能會失效
        • 在改變原型對象時,通常要同時設置constructor屬性
        • var P = function () {};
          var p = new P();
          
          var C = function () {};
          C.prototype = p;
          C.prototype.constructor = C;
          
          var c = new C();
          c.constructor.prototype === p    // true

           

      • Object.getPrototypeOf(obj)    最好的方法

 

  • Object.getOwnPropertyNames()
    • 返回一個數組,成員是參數對象自己的全部屬性的鍵名(無論是否能夠遍歷enumerable),可是不包含繼承的屬性鍵名
    • 只獲取那些能夠遍歷的屬性,使用 Object.keys(某對象) 方法

 

  • Object.prototype.hasOwnProperty()
    • 用於判斷某個屬性是不是自身的屬性,是返回 true,不然返回 false
    • 是 JavaScript 之中惟一一個處理對象屬性時,不會遍歷原型鏈的方法

 

  • in 運算符
    • 表示一個對象是否具備某個屬性。
    • 用於檢查一個屬性是否存在
    • 不區分該屬性是對象自身的屬性,仍是繼承的屬性
      'length' in Date    // true
      'toString' in Date    // true

       

 

  • for(...in...) 循環
    • 得到對象的全部可遍歷屬性(無論是自身的仍是繼承的)
      • var o1 = { p1: 123 };
        
        var o2 = Object.create(o1, {
            p2: { value: "abc", enumerable: true }
        });
        
        for (p in o2) {
            console.info(p);
        }
        // p2    自身的屬性
        // p1    繼承的屬性

        爲了得到對象自身的屬性,能夠採用hasOwnProperty方法判斷一下spa

        • for ( var name in object ) {
              if ( object.hasOwnProperty(name) ) {
                  console.log(name);
              }
          }

           

    • 得到對象的全部屬性(無論是自身的仍是繼承的,也無論能否遍歷),能夠使用下面的函數
      • function inheritedPropertyNames(obj) {
            var props = {};
            while(obj) {
               Object.getOwnPropertyNames(obj).forEach(function(p) {
                    props[p] = true;
               });
               obj = Object.getPrototypeOf(obj);    // 原型對象的原型對象
            }
            return Object.getOwnPropertyNames(props);
        }


        inheritedPropertyNames(Date);
        // [
        //      "caller",
        //      "constructor",
        //      "toString",
        //      "UTC",
        //      ...
        // ]prototype

         
              

 

  • 對象的拷貝
    • 若是要拷貝一個對象,須要作到下面兩件事情
      • 確保拷貝後的對象,與原對象具備 一樣的原型
      • 確保拷貝後的對象,與原對象具備 一樣的實例屬性
    • 第一種方法
      • function copyOwnPropertiesFrom(new, old) {
            Object.getOwnPropertyNames(old).forEach(function (propKey) {
                    var desc = Object.getOwnPropertyDescriptor(old, propKey);
                    Object.defineProperty(new, propKey, desc);
                });
            return new;
        }
        
        function copyObject(old) {
            var new = Object.create(Object.getPrototypeOf(old));
            copyOwnPropertiesFrom(new, old);
            return new;
        }

         

    • 第二種更簡單的寫法,是利用 ES2017 才引入標準的Object.getOwnPropertyDescriptors方法
      • function copyObject(orig) {
            return Object.create(
                Object.getPrototypeOf(orig),
                Object.getOwnPropertyDescriptors(orig)
            );
        }
相關文章
相關標籤/搜索