新しい理解コンストラクタ、プロトタイプとプロトタイプチェーン

あなたがわからない場合は、この記事では、コンストラクタ、プロトタイプとプロトタイプチェーン関連の知識に焦点を当てて コンストラクタが、されていない プロパティは読み取り専用で 、 かつ プロトタイプチェーンが何であるかの違いは、我々はあなたがこの記事を読むことを取ることをお勧めします、私はあなたが思っていますヘルプ。 Symbolconstructorprototype[[Prototype]] __proto__

 

 

コンストラクタ

コンストラクタとは何ですか

constructor オブジェクトのインスタンスを作成するときにコンストラクタは参照を返します。この属性の値は、代わりに関数の名前を含む文字列で、関数自体への参照です。

function Parent(age) {
    this.age = age;
}

var p = new Parent(50);
p.constructor === Parent; // true
p.constructor === Object; // false

コンストラクタ自体が通常の機能の間には差がないが、最初の文字を大文字にする一般的な調節するために、関数です。コンストラクタ関数との差は、使用して通常のことである 生成機能は、コンストラクタの例であり、直接呼び出しは通常の関数です。 new

それは、インスタンスの作成には普通の機能を意味していないん 属性にそれを?必ずしもそうではありません。 constructor

// 普通函数
function parent2(age) {
    this.age = age;
}
var p2 = parent2(50);
// undefined

// 普通函数
function parent3(age) {
    return {
        age: age
    }
}
var p3 = parent3(50);
p3.constructor === Object; // true

シンボルは、コンストラクタそれであります

MDNのご紹介です の Symbol

 関数型の値を返しシンボルを、組み込みオブジェクトのいくつかのメンバーを公開する静的特性を有する、グローバルシンボルレジストリを露出静的メソッドがあり、似そうでないため、オブジェクトクラスに組み込みが、コンストラクタとして不完全です「構文をサポートして」。 Symbol() new Symbol()

Symbol 基本データ型であるが、それは構文をサポートしていないので、それが完了していないため、コンストラクタとして、Chromeはあなたが直接インスタンスを作成したい場合には、コンストラクタではないと考えてい ます。(MDNから) new Symbol() Symbol()

new Symbol(123); // Symbol is not a constructor 

Symbol(123); // Symbol(123)

基本データ型が、しかし   Symbol(123) インスタンスが取得できる 属性値を。 constructor

var sym = Symbol(123); 
console.log( sym );
// Symbol(123)

console.log( sym.constructor );
// ƒ Symbol() { [native code] }

ここだ   constructor プロパティはどこから来ましたか?実際に プロトタイプ、その 戻り値は、関数のプロトタイプのインスタンスを作成し、デフォルトがある 機能。 SymbolSymbol.prototype.constructor Symbol

コンストラクタ値は読み取り専用

以下のための参照タイプのスコア、 属性値を変更することができるが、基本的なタイプは、読み取り専用です。 constructor

そのような継承スキームのプロトタイプチェーンとしてその値がこの状況を変えることができ、十分に理解されている参照型は、我々はする必要があり、正しい再割り当てます。 constructor

function Foo() {
    this.value = 42;
}
Foo.prototype = {
    method: function() {}
};

function Bar() {}

// 设置 Bar 的 prototype 属性为 Foo 的实例对象
Bar.prototype = new Foo();
Bar.prototype.foo = 'Hello World';

Bar.prototype.constructor === Object;
// true

// 修正 Bar.prototype.constructor 为 Bar 本身
Bar.prototype.constructor = Bar;

var test = new Bar() // 创建 Bar 的一个新实例
console.log(test);

 

 

 

基本的なタイプは、のような読み取り専用であるために、当然、 そして全くありません 属性。 1、“muyiy”、true、Symbol null undefined constructor

function Type() { };
var    types = [1, "muyiy", true, Symbol(123)];

for(var i = 0; i < types.length; i++) {
    types[i].constructor = Type;
    types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ];
};

console.log( types.join("\n") );
// function Number() { [native code] }, false, 1
// function String() { [native code] }, false, muyiy
// function Boolean() { [native code] }, false, true
// function Symbol() { [native code] }, false, Symbol(123)

なぜ?彼らは読み取り専用のネイティブコンストラクタを(作成しているためnative constructors)、この例では、オブジェクトの依存性を示す プロパティが安全ではありません。 constructor

新しい達成アナログ

ここでは、の話をしなければならない の実装、および以下のようにコードがあります。 new

function create() {
    // 1、创建一个空的对象
    var obj = new Object(),
    // 2、获得构造函数,同时删除 arguments 中第一个参数
    Con = [].shift.call(arguments);
    // 3、链接到原型,obj 可以访问构造函数原型中的属性
    Object.setPrototypeOf(obj, Con.prototype);
    // 4、绑定 this 实现继承,obj 可以访问到构造函数中的属性
    var ret = Con.apply(obj, arguments);
    // 5、优先返回构造函数返回的对象
    return ret instanceof Object ? ret : obj;
};

プロトタイプ

プロトタイプ

JavaScript それは、プロトタイプベースの言語 (プロトタイプベース言語)、および 他のクラスベースの言語が同じではありません。 Java

各オブジェクトが有するプロトタイプオブジェクトオブジェクトのコンストラクタ関数で、メソッドとプロパティの定義から、そのプロトタイプ、プロトタイプの継承のためのテンプレートとしてこれらのプロパティとメソッドを、オブジェクトの プロパティではなく、オブジェクトのインスタンス自体。 prototype

 

 

上記同図に見ることができるから、Parent オブジェクトは、プロトタイプオブジェクト有し、それぞれ、2つの属性があり、 およびここで 推奨されていません。 Parent.prototype constructor __proto__ __proto__

コンストラクタは プロトタイプを指すポインタを有する、プロトタイプは コンストラクタへのポインタを持って上に示したように、実際に、循環参照です。 Parent Parent.prototype Parent.prototype.constructor

 

 

__ proto__

親プロトタイプは、図で見ることができる。(  )を有し ているプロパティ、アクセス特性(すなわち、機能及びセッターゲッター機能)、オブジェクトを介しての内部へのアクセス (またはオブジェクト    )。 Parent.prototype __proto__ [[Prototype]]null

__proto__ 発音dunderプロトタイプ、組み込みのプロパティES6 Firefoxを使用する最初、以降標準のJavascriptのよう。

[[Prototype]] 外部コードが直接アクセスすることはできません、オブジェクトの内部プロパティです。

標準のECMAScript、SomeObjectのに従う。[[プロトタイプ]]シンボル点SomeObjectのプロトタイプのために。

 

 

ここで使用される オブジェクトのプロトタイプを取得し、 それは各インスタンスであるプロパティが持つ コンストラクタのプロパティで、二人はしかし、同じではありません    、と 同じオブジェクト。 p.__proto____proto__prototypep.__proto__ Parent.prototype

function Parent() {}
var p = new Parent();
p.__proto__ === Parent.prototype
// true

したがって、コンストラクタ   ParentParent.prototype および 図以下の関係。 p

 

 

注意点

__proto__ プロパティ のみWebブラウザとの互換性を確保するために標準化されますが、パフォーマンスの問題がある理由の標準化に加えて、お勧めできませんことができます。より良いサポートするために、それが推奨されます ES6 Object.getPrototypeOf()

オブジェクト変更することで、 プロパティを変更すると属性がパフォーマンスに非常に深刻な影響を引き起こすだろう、と過ごした時間のパフォーマンスは、単純なコストではありません継承する 声明を、それがから継承されたすべて影響します あなたは、パフォーマンスを気にしている場合、オブジェクトをあなたは、オブジェクトを変更しないでください [[Prototype]] obj.__proto__ = ...[[Prototype]] [[Prototype]]

オブジェクトの読み取りまたは変更するには 、属性を、以下のプロトコルが推奨されますが、今回はオブジェクトのセットは、 パフォーマンスに問題がある場合は、まだ遅い操作であり、この操作を回避する必要があります。 [[Prototype]][[Prototype]]

// 获取
Object.getPrototypeOf()
Reflect.getPrototypeOf()

// 修改
Object.setPrototypeOf()
Reflect.setPrototypeOf()

あなたが別のオブジェクトを継承する新しいオブジェクトを作成したい場合は   [[Prototype]] 、それが推奨されますObject.create()

function Parent() {
    age: 50
};
var p = new Parent();
var child = Object.create(p);

ここでは 、新しい空のオブジェクトがあり、オブジェクトpへのポインタがあります child __proto__

新しい用に最適化

前述したように、それが推奨されていません我々が使用するので、 達成シミュレートするために、次のようにコードを最適化。 __proto__ Object.create()

function create() {
    // 1、获得构造函数,同时删除 arguments 中第一个参数
    Con = [].shift.call(arguments);
    // 2、创建一个空的对象并链接到原型,obj 可以访问构造函数原型中的属性
    var obj = Object.create(Con.prototype);
    // 3、绑定 this 实现继承,obj 可以访问到构造函数中的属性
    var ret = Con.apply(obj, arguments);
    // 4、优先返回构造函数返回的对象
    return ret instanceof Object ? ret : obj;
};

プロトタイプチェーン

各オブジェクトは、プロトタイプオブジェクトを有する プロトタイプへのポインタ、およびからメソッドとプロパティを継承するだけでなく、層、終点によってプロトタイププロトタイプオブジェクト、そのような層を有していてもよいですこの関係は、と呼ばれるプロトタイプチェーン(プロトタイプalberghieraカテナ)プロトタイプオブジェクトのチェーンによって他のオブジェクトに定義されたプロパティおよびメソッドを有します。 __proto__ null

ここでは、例を参照してください

function Parent(age) {
    this.age = age;
}

var p = new Parent(50);
p.constructor === Parent; // true

ここで のポイント、することを意図していない インスタンスが存在する属性?そうではありません。 parent.constructor Parent parent constructor

私たちは、次の印刷 を知るための値を。 parent

 

 

図インスタンスオブジェクトから見ることができ ていない プロパティを、プロトタイプチェーンを通じてルックアップするためにある、最終的に見つけるために、 属性ポイントを p constructor __proto__ constructor Parent

function Parent(age) {
    this.age = age;
}
var p = new Parent(50);

p;    // Parent {age: 50}
p.__proto__ === Parent.prototype; // true
p.__proto__.__proto__ === Object.prototype; // true
p.__proto__.__proto__.__proto__ === null; // true

次の図は、プロトタイプチェーンの動作機構を示しています。

 

 

概要

  • Symbol 彼らは構文をサポートしていないので、コンストラクタとして、それは、完全ではないが、そのプロトタイプで プロパティ、つまり new Symbol()constructor Symbol.prototype.constructor

  • 参照タイプの 属性値を変更することはできないが、基本的なタイプは読み取り専用で、もちろん、 と 何の 財産。 constructornull undefined constructor

  • __proto__ 各インスタンスの属性は上でありprototype 、コンストラクタの属性があり、二人は同じ、しかしではない   p.__proto__ 、と 同じオブジェクト。 Parent.prototype

  • __proto__ プロパティ それが標準化されているが、理由はパフォーマンスの問題の推奨されていない、使用することをお勧めします ES6Object.getPrototypeOf()

  • 各オブジェクトは、プロトタイプオブジェクトを有する プロトタイプへのポインタ、およびからメソッドとプロパティを継承するだけでなく、層、終点によってプロトタイププロトタイプオブジェクト、そのような層を有していてもよいプロトタイプチェーンです、。 proto null

おすすめ

転載: www.cnblogs.com/duanlibo/p/11642222.html