Object再認識(一)

9095 ワード

内容がちょっと多いので、二つの内容に分けて皆さんと分かち合います.確かに理解しにくいところがあります.多くの手で実現して、効果を見てください.
ずっと聞いていますが、JavaScriptの中では全て対象となります.
本人が慎重に検討した結果、この言葉は確かに間違っていないことが分かりました.(無駄話じゃないですか?虚無ではないのはあなたで言います.)
今日はあえてみんなと一緒にJavaScriptの重さのObjectを討論します.Objectの背後にあることを知る. 読書の合間には、ゆっくり休んでください.
1.オブジェクトの作成
最初の小さな問題を始めて、どのようにオブジェクトを作成するかを見てください.オブジェクトを作成するには4つの方法があります.次のいくつかの方法はいずれもオブジェクトを作成できますが、作成後の表現は少し違っています.具体的には、プロトタイプおよびthisの指向性問題として表現される.興味のある読者はクリックして関連記事を見ることができます.ここでは詳しく紹介しません.(怠けて)
JavaScriptの原型問題を徹底的に理解する
JavaScriptのthisポインタを深く理解する
注意点:
4つの方法でオブジェクトを作成します.プロトタイプとthisポインタの表現が異なる以外に、構造関数の指向性も違います.(この場合、手動でコンストラクタを指定しない場合)
  • 字面量方式で作成されたオブジェクト.構造関数はfunction Object() {}
  • です.
  • 構築関数が作成されます.コンストラクタは、関数自体
  • です.
  • Object.createによって作成されたオブジェクトの構造関数は、入力originの構造関数
  • である.
  • class方式で作成され、自身も構造関数として機能します.
  • 1.1字面量方式の作成
    const obj = {} //       [Function: Object]
    1.2コンストラクタの作成
    function Obj() {}
    
    const obj = new Obj() //       [Function: origin]
    1.3 Object.creat作成
    const origin = {a: 1, b: 2}
    
    const target = Object.create(origin) //       origin      
    1.4クラス方式の作成
    class Origin {}
    
    const target = new Origin() //      [Function: Origin]
    2.属性と方法
    注:
  • 公式版
  • 属性はこのオブジェクトの属性であり、方法はこのオブジェクトが持つ機能
  • である.
  • 通俗版
  • 属性は値であり、実行できません.
  • 方法は関数であり、実行可能である.
  • 2.1属性と方法の取得
    1.決定したkey属性を取得し、.演算子または括弧を使用する.
    const obj = {
      a: 1,
      b: 2,
      c: 3,
      d: function () {}
    }
    
    obj.a === obj['a']// 1
    obj.b === obj['b'] // 2
    obj.c === obj['c'] // 3
    obj.d === obj['d'] // function (){}
    2.計算が必要なkay値を取得するには、中かっこのみを使用することができます.
    const obj = {
      a1: 1,
      a2: 2,
      a3: 3,
      a4: function (){}
    }
    
    for(let i = 1;i < 5;i ++) {
      obj['a' + i]
    }
    // 1,2,3,function (){}
    注意:
    オブジェクトにあるkeyが含まれていない場合、undefinedが取得される.
    たとえば:
    const obj = {}
    
    obj.c() // TypeError: obj.c is not a function
    objにはcという方法が含まれていないので、undefinedが取得された.この値は関数ではなく、エラーを実行します.
    次のように修正できます.
    const obj = {}
    
    typeof obj.c === 'function' && obj.c()
    このようにしてもいいという読者がいるかもしれません.このような書き方は下のような場合でもエラーが発生します.
    const obj = {
      c: 1
    }
    
    obj.c()
    したがって、私たちが取得するべきobj.c && obj.c()は関数であるということを明確に判断しなければならない.
    2.2どのようにして対象にある値が含まれているかを判断しますか?
    このセクションの開始前に、まず、小さな問題について、どのようにオブジェクトにkeyの値が含まれているかどうかを判断しますか?
    1.keyの属性を使って取得する
  • は、2.1か否かを判断するだけでよい.
  • この方法には欠点があります.この値がundefinedであると判断ミスが発生します.
    const obj = {
      c: undefined
    }
    
    console.log(obj.c === 'undefined') //    true,  obj     c  key
    2.undefined
  • は、あるin
  • を含む.
    //     key
    function A () {
      this.b = 1
    }
    const a = new A()
    console.log('b' in a) // true
  • は、あるkey
  • を含まない.
    //      key
    function A () {
    }
    const a = new A()
    console.log('b' in a) // false
  • が照会したkeyの値がkeyの場合
  • .
    //      key
    function A () {
      this.b = undefined
    }
    const a = new A()
    console.log('b' in a) // true
  • が照会したundefinedは、プロトタイプチェーン上に存在する
  • .
    function A () {
    }
    
    Object.prototype.b = 1
    const a = new A()
    
    console.log('b' in a) // true
    注意点:
    短所:key方法は、現在inがオブジェクト自体にあるか、それともプロトタイプチェーンにあるかを判断できない.この場合には、次のような方法が必要です.
    3.key属性が自身に存在するかどうかを問い合わせる.
  • はプロトタイプチェーン上に存在します.
    function A () {}
    
    Object.prototype.b = 1
    const a = new A()
    
    console.log(a.hasOwnProperty('b')) // false
  • は自分自身に存在します.
    function A () {
      this.b = 1
    }
    
    const a = new A()
    
    console.log(a.hasOwnProperty('b')) // true
  • 属性値はhasOwnProperty
  • である.
    function A () {
      this.b = undefined
    }
    
    const a = new A()
    
    console.log(a.hasOwnProperty('b')) // true
    まとめ:
  • 属性取得が属性値がundefinedであると判断できない場合
  • undefined方法では、属性はオブジェクト自体か、それともプロトタイプチェーン上かを判断することができません.
  • inは、属性が自身に存在するかどうかを判断することができ、属性値がhasOwnPropertyであると判断することもできる
  • .
    2.3オブジェクトの属性を削除する
    オブジェクトを削除する属性はundefined方法を使用することができますが、この方法の性能はあまり優れていません.
    const obj = {
      b: 1,
      c: 2
    }
    
    delete obj.b
    console.log(obj) // {c: 2}
    休みの間,この文章は長々として,順を追って漸進的に来ることができる.
    2.4属性分類deleteでは、属性は2つに分類される.データ属性とアクセス属性.
    データ属性は、JavaScriptConfigurableEnumerableWritableValueの4つの属性記述子を含む.
    アクセス属性は、ConfigurableEnumerableSetGetConfigurable、Enumerable、Writeable、Value、Set、Getの4つの属性記述子を含む.
    属性の説明は6つのタイプがあることが分かります.Object.defineProperty(obj, key, config) 注意:
    ディスクリプタは、Object.defineProperties(obj,config) 方法によってのみ修正され得る.
    たとえば:
    const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    //     
    Object.defineProperty(obj, 'a', {
      enumerable: true,
      writable: true,
      configurable: true
    })
    
    //     
    
    Object.defineProperties(person, {
      a: {
        enumerable: true,
        writable: true,
        configurable: true
      },
      b: {
        enumerable: true,
        writable: true,
        configurable: true
      }
    }
    1.記述子の紹介Configurable:属性をdeleteで削除してもいいかどうか、属性を再定義してもいいかどうか、ディスクリプタを修正してもいいかどうか、属性スワップが可能かどうか.
  • trueであり、上述の動作はいずれも
  • である.
    const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    Object.defineProperty(obj, 'a', {
      configurable: true
    })
    
    delete obj.a
    Object.defineProperty(obj, 'a', {
      value: 11
    })
    Object.defineProperty(obj, 'a', {
      enumerable: true
    })
    Object.defineProperty(obj, 'a', {
      set() {}
    })
  • falseの厳格なモードでエラーが発生し、通常モードでのフィルタリング動作
  • const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    Object.defineProperty(obj, 'a', {
      configurable: false
    })
    
    delete obj.a
    Object.defineProperty(obj, 'a', {
      value: 11
    })
    Object.defineProperty(obj, 'a', {
      enumerable: true
    })
    Object.defineProperty(obj, 'a', {
      set() {}
    })
    Enumerable:列挙できるかどうか
    const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    
    //   true    ,   
    Object.defineProperty(obj, 'a', {
      enumerable: true
    })
    
    for(let item in obj) {
      console.log(item) // a, b, c       a
    }
    
    //  false   ,    
    Object.defineProperty(obj, 'a', {
      enumerable: false
    })
    
    for(let item in obj) {
      console.log(item) // b, c       a
    }
    Writable:属性の値を変更できるかどうか、それを加えると、データ属性になります.
    const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    
    //   true       
    Object.defineProperty(obj, 'a', {
      writable: true
    })
    obj.a = 2
    console.log(obj.a) // 2
    
    //  false                 
    Object.defineProperty(obj, 'a', {
      writable: false
    })
    obj.a = 2
    console.log(obj.a) // 1
    Value:属性のデータ値に加えて、データ属性になります.
    const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    Object.defineProperty(obj, 'a', {
      value: 11
    })
    console.log(obj.a) // 11
    Set:属性を書き込むときに呼び出し、これを加えると、アクセス属性になります.
    const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    Object.defineProperty(obj, 'a', {
      set() {
        console.log('a     ')
      }
    })
    
    obj.a = 2 // a     
    Get:属性を読み出すときに呼び出し、これを加えると、アクセス属性になります.
    const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    Object.defineProperty(obj, 'a', {
      get() {
        console.log('  a  ')
      }
    })
    
    obj.a //   a  
    2.属性互換:
    データ属性-->アクセス属性Writable、ValueのいずれかをSet、Getのいずれかに置き換える.
    アクセス器のプロパティ->データのプロパティSet、GetのいずれかをWritable、Valueのいずれかに置き換える.
    例は次に続きます.
    3.ある属性の説明を取得する(この属性がデータ属性かそれともアクセス属性かを確認する)
    属性の説明を確認するには、Object.getOwnPropertyDescriptor(obj, key)を使用して見ることができます.
    const obj = {
      a: 1
    }
    console.log(Object.getOwnPropertyDescriptor(obj, 'a'))
    // { value: 1, writable: true, enumerable: true, configurable: true }
    
    Object.defineProperty(obj, 'a', {
      get() {
        console.log('  a  ')
      }
    })
    console.log(Object.getOwnPropertyDescriptor(obj, 'a'))
    /*
    {
      get: [Function: get],
      set: undefined,
      enumerable: true,
      configurable: true
    }
    */
    この例は、 の正確さを検証することができ、getaのディスクリプタに設定すると、aはアクセス属性に変化する.
    以下に続く:Object再認識(二)