2016-12-05 34 views
2

私はプラグイン(Pikaday)を修正し、私自身の少しの機能性を追加しようとしています。JavaScript:プロトタイプ内でメソッドを使用する方法は?

プラグインはproto-typeシステムを使用して構築されており、その中に自分のファンクションを追加しました。

Pikaday.prototype = { 

    //OTHER PARTS OF PLUGIN 

    showYearPicker: function() 
     { 
      document.getElementsByClassName('pika-year-label').onclick=function(){ 
       console.log("asfd"); 
      } 
     }, 

    //OTHER PARTS OF PLUGIN 
} 

return Pikaday; 

どのように実際にこのメソッドをトリガするのですか。指定された要素をクリックしても機能しません。

プラグインの一部としてこの機能をどのように含めることができますか?

Full code(マイナスマイナス)は誰でも興味があればここにいます。

+0

@ 4castleいいえ、私はそうではありません。私はそうすべきだと思ったが、プロトタイプ内の他の機能が呼び出されないので、これは私を混乱させた。私はプロトタイプを持つすべての関数が自動的に呼び出されたと思った。 – MeltingDog

+1

'onclick'リスナーをループに追加する必要がある。 'getElementsByClassName'は、単一の要素ではなく、リストを返します。 (そして、いいえ、プロトタイプ関数は自動的に呼び出されず、 'new Pikaday()。showYearPicker()'で呼び出さなければなりません) – 4castle

+0

getElementsByClass nameはNodeListを返します。あなたはそれにonclickを割り当てることはできません。 – Phix

答えて

3

簡単な言葉で関数のプロトタイプにメソッドを定義するということは、この関数のすべてのインスタンスからプロトタイプチェーンをリンクするオブジェクトにメソッドを定義したことを意味します。

これは、その機能のすべてのインスタンスで共通の「親」または「上のオブジェクト」と考えることができます。

したがって、メソッドを使用するには、プラグインをインスタンス化し、その関数を呼び出す必要があります。これが何をするか

function Pikaday() {} 
 

 
Pikaday.prototype = { 
 

 
    showYearPicker: function() { 
 
    console.log('called'); 
 
    } 
 
} 
 

 
let pikaday = new Pikaday(); 
 
pikaday.showYearPicker(); // <-- call the function on the prototype

pikadayshowYearPickerがそれに定義されているかどうかをチェックし、それがないので、プロトチェーンを上がると、そのオブジェクトがそれを持っている場合は、チェックしていますします。言い換えれば

が、これは、JSエンジンは舞台裏で何をするか、本質的である:

let pikaday = new Pikaday(); 
pikaday.__proto__.showYearPicker(); 

protoはここだけのデモのために、そのは、ごく最近、レガシー目的のためにES6で標準化されていることに注意してください、しかし、この振る舞いJSエンジンに残す必要があります(specはこのプロトリンクを[[Prototype]]と呼んでいます)。必要

場合は、プロトタイプにアクセスするための適切な方法は、あなたのコードがあると

function Pikaday() {} 
 

 
console.log(
 
    Object.getPrototypeOf(new Pikaday()) === Pikaday.prototype 
 
); 
 

 
console.log(
 
    Reflect.getPrototypeOf(new Pikaday()) === Pikaday.prototype 
 
);

一つの問題(あなたは意味的に明確Reflect.getPrototypeOfを使用することができます+ ES6で)Object.getPrototypeOfを使用することですgetElementsByClassNameは、このクラスを持つノードのNodeList(配列ではない)を返します。

これはどちらかでなければなりません。このリストをループして、各要素に

let nodes = document.getElementsByClassName('pika-year-label'); 
Array.from(nodes) // convert NodeList to an array so we can use forEach 
    .forEach(node => { 
    // attach a handler on each node 
    node.onclick = function(){ 
     console.log("asfd"); 
    } 
    }); 

// Side Note: You can also use array spread to convert the node list to an array 
// [...nodes].forEach(...) 

または代わりに行動を委任するすべての要素のための共通の親にハンドラをアタッチするハンドラをアタッチ意味。

document.body.onclick = function(e) { 
    if (e.target.classList.contains('pika-year-label')) { 
    console.log("asfd"); 
    } 
} 

あなたが唯一の既存の関数のプロトタイプにこの機能を追加したい場合は最後に、それを行うための一つの方法は、単にそのプロトタイプのメソッドとして定義することです:

function Pikaday() {} 
 

 
// define a method on the existing prototype 
 
Pikaday.prototype.showYearPicker = function() { 
 
    console.log('called'); 
 
}; 
 

 
let pikaday = new Pikaday(); 
 
pikaday.showYearPicker(); // <-- call the function on the prototype

+0

実際には '__proto__'は非推奨です。 ['Object.getPrototypeOf'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf)が推奨される標準です。 – 4castle

+0

これはプロトタイプを取得する正しい方法ですが、__proto__はES6の標準に追加されました – nem035

+0

このような詳細な返信を書く時間を入れていただきありがとうございます:) – MeltingDog

関連する問題