2016-11-11 5 views
4

私はすべてのことを深く知る必要がある人です。だから私は教えられた多くの科目を通っています。私はプロトタイプ継承の深みに足を踏み入れました。
私はES5でどのように動作するかについて明確なビジョンを持っています(すべての関数には、この特殊なプロトタイププロパティがあり、それが基になっているオブジェクトを指しています。 。どのくらいES6クラスがES5スタイルと異なるのですか?

だから、今のは、ES5の例を見てみましょう:

function Bunny(name) { 
    this.name = name 
} 

Bunny.prototype.sayName = function() { 
    console.log('Im',this.name) 
} 

この1つはかなり明確である:機能バニーは、新しいオブジェクトに割り当てることになるだろう引数nameを取得します。

次の行は、現在の名前を返す関数のプロトタイプに関数を追加します。

さんは今ES6クラスを見てみましょう。ここ

class Fox{ 
    constructor(name){ 
     this.name = name; 
    } 

    sayName() { 
     console.log('Im', this.name) 
    } 
} 

同じもの:ここConstructorは、私たちのバニー機能のようなものです。しかし、キツネのsayNameはバニーのsayNameと同じではありません。
のは、インスタンスを作成してみましょう:

let bunny = new Bunny('Henry'); 
let fox = new Fox('Jerry'); 

そして今は、彼らのプロトタイプを確認してください。

console.log(Object.getPrototypeOf(bunny)) 
console.log(Object.getPrototypeOf(fox)) 

我々は何を得るのですか?

//using repl.it - ES6 
{ sayName: [Function] } 
{} 

なぜですか?

バニーのプロトタイプに直接機能sayNameを設定している可能性があると思いました。だから私はこれにそれを変更しました:

function Bunny(name) { 
    this.name = name 

    //Warning - Bad practice ahead! 
    this.sayName = function() { 
     console.log('Im',this.name) 
    } 
} 

結果:

意味
console.log(bunny.hasOwnProperty('sayName')) 
console.log(fox.hasOwnProperty('sayName')) 

foxは上sayNameを所有していない:いないこの場合、意味を持っているでしょう

//using repl.it - ES6 
{} 
{} 

彼のプロトタイプは、それがそれを持っていることを示しています。私はここに何かを逃していますかなぜ彼らは違うのですか?

+0

なぜ2番目の例は悪い習慣ですか? – evolutionxbox

+0

@evolutionxboxこれは、インスタンスごとに新しい関数を作成するためです。 –

+0

'console.log'を使ってオブジェクトを検査しないでください。 'console.dir'を使います。 –

答えて

7

ES6クラスでは、すべてのメソッドが列挙できません。したがって、ES6クラスのインスタンスのプロトタイプをログに記録すると、空のオブジェクトのように見えます。

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

const obj = new (class {method() {}}); 
 

 
console.log(Object.getPrototypeOf(obj)); // {} 
 
console.log(typeof Object.getPrototypeOf(obj).method); // function

あなたはそれが列挙可能になり、クラスのプロトタイプのプロパティに割り当てることによってメソッドを定義します。唯一の独自のプロパティのための

const TestClass = function TestClass() {}; 
 
Object.defineProperty(TestClass.prototype, 'method', { 
 
    value: function() {}, 
 
    writable: true, 
 
    enumerable: false, 
 
    configurable: true, 
 
}); 
 
const obj = new TestClass(); 
 

 
console.log(Object.getPrototypeOf(obj)); // {} 
 
console.log(typeof Object.getPrototypeOf(obj).method); // function


そしてfox.hasOwnProperty('sayName')戻りfalsehasOwnProperty()ためのチェック、およびsayNameは次のとおりです。あなたがES6クラスと同じ効果を達成したい場合は、代わりにObject.defineProperty()を使用することができますプロトタイプチェーンで。 trueを返し'sayName' in fox:あなたはあまりにもプロトタイプチェーン内のプロパティをチェックしたい場合は、in演算子を使用することができます。


MDNのEnumerability and ownership of propertiesも参照してください。

+0

ああ、それは私が逃したものです!良いですね! また、私はバーベルトランスファーにコードを貼り付けて、ES5にコードを貼り付けました。 コンストラクタ内のすべてのプロパティを調べ、それらが列挙可能かどうかをチェックするforループがあります - > 'methods'はそうではありません!それを '.propertyIsEnumerable'でチェックするとfalseになります。 また、私は 'fox'と' fox.prototype'の両方で '.hasOwnProperty'をチェックして同じ結果を得ました。しかし私は私の質問でそれを言及しなかった、私の悪い。 – Krizzu

関連する問題