js対象を深く理解する


この文章は収録しています.「JavaScript深く探求する道」
前言
対象はJavascriptの基本タイプです.オブジェクトは、複数の値(元の値または他のオブジェクト)をまとめて、名前でこれらの値にアクセスできる複合値です.オブジェクトは属性の無秩序集合とも見なされる.各属性は一つの名前/値ペアです.JavaScriptオブジェクトは、プロトタイプと呼ばれるオブジェクトから属性を継承することもできます.
注意したいのはES 6の中で対象に対してもいくつかの拡張をしたので、この文章は特に説明していません.もしあなたが理解したいなら、阮先生のES 6書籍を見てもいいです.
対象の属性を大きく三つに分けることができます.
  • 内蔵オブジェクト:ECMAScript仕様で定義されているオブジェクトまたはクラスです.配列、関数、日付、正規表現などはすべてオブジェクトを内蔵しています.
  • 宿主オブジェクト:JavaScript解析器によって埋め込まれた宿主環境であり、クライアントJavaScriptにおいてウェブページの構造を示すHTMlementは画像に対しても宿主オブジェクトである.宿主の対象も内蔵の対象とすることができます.
  • カスタムオブジェクト:実行中のJavaScriptコードから作成されたオブジェクトです.
  • また二つの属性があります.
  • 自己属性:直接隊形に定義された属性
  • です.
  • 継承属性:オブジェクトの原型オブジェクトに定義された属性
  • です.
    オブジェクトを作成
    1.対象文字数(対象直接量とも称する)
    オブジェクトを作成する最も簡単な方法は、JavaScrippotコードにオブジェクトの直接量を使用することです.
    let obj = {
        name: 'web',
        age: 23,
        sex: 'man'
    }
    
    オブジェクトの属性名は、Symbol値とすることができ、ES 6が新たに作成されたデータタイプです.オブジェクトの直接量は、演算ごとに新しいオブジェクトを作成して初期化する表式です.オブジェクトの直接量を計算するたびに、属性値を計算します.つまり、繰り返し呼び出される関数の中の循環体にオブジェクトの直接量が使われると、多くの新しいオブジェクトが作成され、毎回作成されるオブジェクトの属性値が異なる可能性があります.
    2.newで作成したオブジェクト
    new演算子は新しいオブジェクトを作成して初期化し、キーワードnewは関数として呼び出されます.ここでの関数はコンストラクタと呼ばれ、コンストラクタは新たに作成されたオブジェクトを初期化するために用いられます.JavaScript言語の核心にあるオリジナルのタイプはすべて構造関数を内蔵しています.
    let obj = new fun();
    let ary = new Array();
    また、newによって作成されたコンストラクタを使用するとプロトタイプがないことを知る必要がありますが、彼らは最終的にObject.prototypeを継承します.
    let ary = new Array();
    ary.prototype // undefind
    3.Object.creat()メソッド作成対象Object.create()この方法は、2つのパラメータを有する新しいオブジェクトを作成し、最初のパラメータはこのオブジェクトのプロトタイプである.第二のパラメータは、オブジェクトの属性をさらに説明するために使用されます.Object.create()は、あるオブジェクトに対して呼び出す方法ではなく、静的関数である.
    let o = {
        name: 'jhon',
        age: 23
    }
    let obj = Object.create(o);
    
    obj.name // jhon
    obj.__proto__ === o // true obj         o
    obj.name === o.name // true
    その二つ目のパラメータは属性に対する数値です.次に、オブジェクト属性の特徴に関する設定について説明します.
    オブジェクトの属性操作
    1.クエリー
    オブジェクト属性のクエリーには、.演算子、[]演算子、またはES 6を使用して提供できるReflect.get()方法があります.
    let o = {
            name: 'jhon',
            age: 23
        }
    
    console.log(o.name) // 'jhon'
    console.log(o['name'])  // 'jhon'
    console.log(Reflect.get(o, 'name'))  // 'jhon'
    []にとって、四角い括弧内は、計算結果が文字列である式(直接文字列でも良い)である必要があり、一般的に動的な属性を取得するために用いられる.また、私はES 6について説明していません.ES 6を知りたいです.阮一峰先生のエス6基礎に関する本を見てもいいです.
    2.削除deleteオペレータは属性を削除することができます.操作数は属性アクセス式であるべきです.deleteは属性と宿主オブジェクトとの連絡を切断するだけで、属性の中の属性を操作しないです.
    let o = {
        name: 'jhon',
        age: 23,
        other: {
            address: 'HangHai',
        },
    }
    
    var obj = o.name;
    
    delete o.name
    
    console.log(o.name) // underfind
    console.log(obj) // 'jhon'
    また、delete演算子は、自己属性のみを削除することができます.継承属性を削除することはできません.また、いくつかの属性設定がfalseの属性として削除することもできません.また、大域関数とvarによって宣言された変数も削除できません.
    3.継承
    属性は継承可能で、JavaScriptオブジェクトには「固有属性」があり、原型オブジェクトから継承される属性もあります.例えば関数のtoString()方法はObjectのプロトタイプから継承します.
    4.検出
    属性を検出するホームは、in演算子、hasOwnPreperty()およびprotertyIsEnumerable()方法を使用することができる.
    let o = {
        name: 'jhon',
        age: 23,
        other: {
            address: 'HangHai',
        },
    }
    
    //   in                    
    //       
    
    console.log('name' in o) // true
    console.log('toString' in o) // true
    
    //hasOwnProperty()               
    
    console.log(o.hasOwnProperty('name')) // true
    console.log(o.hasOwnProperty('toString')) // false
    
    propertyIsEnumerable()hasOwnProperty()の拡張版であり、独自の属性であることを検出し、この蘇生のエニュメレーション性がtrueである場合にのみ、trueに戻ります.
    // toString         
    console.log(o.propertyIsEnumerable('toString')) // false
    
    5.列挙の属性for/inエルゴード属性を使用することができます.オブジェクトの固有属性を遍歴するために、以下の方法を使用することができます.
     let o = {
        name: 'jhon',
        age: 23,
        other: {
            address: 'HangHai',
        },
    }
    
    let obj = {}
    
    for (prop in o){
      if(o.hasOwnProperty[prop]) continue;
      obj[prop] = o[prop];
    }
    6.属性のセットとget
    ECMAScrit 5において属性値は、1つまたは2つの方法で代替できるものであり、この2つの方法は、getterおよびsetterであり、getterおよびsetterによって定義される属性を「アクセサ属性」と呼び、「データ属性」とは異なる.
    プログラムがアクセサ属性の値を照会すると、JavaScriptがgetterメソッドを呼び出します.この方法の戻り値は属性保存式の値であり、プログラムがデポジット属性の値を設定すると、JavaScriptはsetterメソッドを呼び出し、赋値式の右側の値をパラメータとしてsetterに入力します.
    データの属性とは違って、アクセサの属性は書き込み可能性がありません.もし属性が同時にgetterとsetterの方法を持っているなら、それは読み/書きの属性であり、もしそれがgetterの方法しかないなら、彼は読み取り専用の属性であり、もしそれがsetterの方法しかないなら、彼は属性だけを書くのです.
    アクセサ属性を定義する最も簡単な方法は、オブジェクトの直接量を使用する文法です.
    let o = {
        name: 'jhon',
        age: 23,
        get g(){
            console.log("       ")
            return this.age + 10;
        },
        set g(value){
            console.log('       : '+ this.age)
        },
    
    } 
    
    console.log(o)
    o.g  //        
    o.g = 10  //        : 23
    
    属性のいくつかの特徴
    属性には名前と値のほかに、彼らが書いてもいい、列挙してもいい、構成可能な特性が含まれています.
    データ属性の特性には、
  • value
  • 書き込み可能性writableデフォルトtrue
  • エニュメレーションenumerableデフォルトtrue
  • 構成可能性configurableデフォルトtrue
  • アクセサの属性特性には以下のものがあります.
  • 読み出しget
  • 書き込みset
  • は、挙げられないことがあります.enumerable
  • 構成可能性configurable
  • プロパティ特性のクエリーと設定操作を実現するために、ECMAScript 5は「プロパティ記述子」というオブジェクトを定義します.defineProperty()は、ある属性の特性を設定します.
    let obj = {
        name: 'jhon',
        age: 23,
    }
    Object.defineProperty(obj,'name',{
        value: 'King', //      
        writable: false,  //        
        enumerable: true, //       
        configurable: true //       
    
    })    
    
    console.log(obj.name); // 'King'
    obj.name = 'Tom'; //       
    console.log( obj.name); // 'King'
    アクセサの属性特性を設定することもできます.
    let obj = {
        name: 'jhon',
        age: 23,
    }
    //    name        
    Object.defineProperty(obj,'name',{
        get: function(){
        return '        '
        },
        enumerable: true, //       
        configurable: true //       
    
    })    
    
    console.log(obj.name);
    definePeoperties()は、複数の属性の特性を設定する.definePeoperties()を使用して、複数の属性の特性を設定することができます.
    let obj = {
             name: 'jhon',
             age: 23,
    }
    Object.defineProperties(obj,{
        name:{
        get: function(){
        return '        '
        },
        enumerable: true, //       
        configurable: true //       
        },
        age:{
            writable: false, //     age
        }
    
    })    
    
    console.log(obj.name); //        
    
    obj.age = 10;
    console.log(obj.age) // 23
    getOwnpropertyDescriptor()は、オブジェクト固有属性の属性記述を取得する.
    let obj = {
        name:'jhon'
    }
    
    let descriptor = Object.getOwnPropertyDescriptor(obj,'name');
    
    // Object {value: "jhon", writable: true, enumerable: true, configurable: true}
    console.log(descriptor)
    オブジェクトの3つの属性
    1.原型の属性
    オブジェクトのプロトタイプ属性は、属性を継承するためのもので、プロトタイプのインスタンスが作成された当初から設定されていました.オブジェクトの直接量によって作成されたオブジェクトObject.prototypeは、彼らのプロトタイプとして、newによって作成されたオブジェクトに、構造関数prototype属性を使用して、Object.create()によって作成されたオブジェクトに最初のパラメータ(nullでもよい)を使用します.彼らのモデルとして
    ECMAScript 5では、オブジェクトをパラメータとしてObject.getPrototypeOf()に導入し、彼のプロトタイプを確認することができる.
    let obja = {
     name:'jhon'
    }
    
    let proto = Object.getPrototypeOf(obja);
    console.log(proto) //   Objcet   
    オブジェクトが別のオブジェクトのプロトタイプであるかどうかを検出するためには、isPrototypeOf()方法が使用されてもよい.
         
    function fun(name){
        this.name = name
    }
    
    fun.prototype = function(){
        console.log("  ")
    }
    
    let newFun = new fun('jhon');
    
    // true
    console.log(fun.prototype.isPrototypeOf(newFun))
    
    //           instanceof                   
    
    console.log( newFun instanceof  fun) // true
    2.クラスの属性
    オブジェクトの雷属性は、オブジェクトのタイプ情報を表す文字列で、間接的な方法で調べられます.デフォルトのtoString()メソッド(Object.prototypeから継承)は、このようなフォーマットの文字列を返します.[object class]Object.prototype.toString.call()を通して対象のクラスを検出できます.
    function fun (){
    
    }
    
    let className = Object.prototype.toString.call(fun);
    
    console.log(className) // [object Function]
    3.拡張可能性
    オブジェクトの拡張可能性は、オブジェクトに新しい干支を追加できるかどうかを表します.すべての内蔵オブジェクトとカスタムオブジェクトは、明示的に拡張可能です.ここでは、Object.esExtensible()を通じて、オブジェクトが拡張可能かどうかを判断することができる.
    let obj = {
        name: 'jhon',
        age: 23,
    }
    
    // true    obj       
    console.log(Object.isExtensible(obj))
    オブジェクトを拡張不可能に変換するには、Object.preventExtensions()を使用することができます.
    let obj = {
            name: 'jhon',
            age: 23,
        }
    
    Object.preventExtensions(obj);
    
    obj.address = 'BeiJing'
    
    console.log(obj) // obj       address  
    console.log(Object.isExtensible(obj)) // false
    注意オブジェクトを拡張不可に変換すると、拡張可能に変換できなくなります.
    オブジェクトを拡張不可に変換したい場合、オブジェクトの所有属性はすべて設定不可(すなわち閉じられたオブジェクト)に設定されています.Object.seal()を使用して、閉じたオブジェクトを判読することができます.
    オブジェクトを拡張不可に変換したい場合、オブジェクトの所有属性はすべて設定不可で読み取り専用(つまり凍結対象)に設定され、Object.isSealed()を使用することができ、オブジェクトのアクセサ属性がsetter方法を有する場合、アクセサ属性は影響を受けない.Object.frozen()を使用して、オブジェクトが凍結されているかどうかを検出する.Object.isFrozen()Object.preventExtensions()Object.seal()、およびObject.frozen()は、いずれも着信されたオブジェクトに戻る.
    オブジェクトの方法
    使用したJavaScriptオブジェクトは全部Objcet.prototypeから属性を継承しています.(プロトタイプ表示によって作成されていないオブジェクトを除いて)これらの方法は詳しく紹介していません.
    1.toString()方法
    2.toLocale String()方法
    これはtoString()方法を呼び出し、対応する値を返しただけで、DateおよびNumber類はこの方法をカスタマイズした.
    3.toJson()方法Objcet.prototypeは、実際にはtoJson()方法を定義していないが、プログレッシブを実行する必要があるオブジェクトに対しては、JSON.stringify()方法が起動される.
    4.valueOf方法
    JavaScriptがオブジェクトを文字列ではなく元の値に変換する必要があるときに呼び出します.
    終了
    参考書:「JavaScript権威の手引き」