2017-11-01 6 views
1

私は以下のことを達成するために探しています。既存のオブジェクトに "名前空間"を持つプロトタイプを使用する

HTMLSpanElement.prototype.testNS = { 
    _this: this, 
    testFunc: function() { 
    console.log(this.innerHTML) //undefined as expected as this is the testFunc object 
    }, 
    testFunc2: function() { 
    console.log(this._this) //Window object 
    } 
} 

ここでの目標は、この場合はいくつかのヘルパー関数を直接スパン要素に追加することです。私が持っていた場合

ので、以下:

<span>test</span> 

私は機能が保持していることを私は知っている

spanElement.testNS.testFunc() 

をスパンを見つけて、「テスト」を返すようにこのコードを呼び出すことができ、それの範囲は親です私がそれを好きなときに...

HTMLSpanElement.prototype.testFunc = function() { 
    console.log(this.innerHTML) 
} 

しかし、私は少しコードを整理しようとしています関数を追加したときに関数が来てスコープを保持する方法を見つけることができない場合は、通常のJSONオブジェクトを使ってこのスコープを_this: thisに取得するだけで "ウィンドウ"のグローバルスコープが返されます。

+0

* *「これはtestFuncオブジェクトがあるとして、」 'this':testNSは、それが呼び出されてされているオブジェクト(再び、スパン)のコンテキストで呼び出されるので、これは動作します関数オブジェクト自体を決して参照しません。この関数を 'spanElement.testNS.testFunc()'として呼び出すと、 'panElement.testNS'を参照します。 –

答えて

3

免責事項:あなたが構築された上でプロトタイプを変更しようとすべきではありません-in型、特にホストオブジェクト。それは悪い考えです。


あなたのアプローチがあなたのために働いていない理由は、機能がthisとしてtestNSオブジェクトと呼ばれていることです。

ゲッター関数を持つプロパティとしてtestNSを定義した場合は、Object.definePropertyを使用してください。この動作の理由は、get関数プロパティは(スパンされるであろう)アクセスされているオブジェクトのコンテキストで実行することである:

Object.defineProperty(HTMLSpanElement.prototype, 'testNS', { 
 
    get: function() { 
 
    var _this = this; 
 
    return { 
 
     testFunc: function() { 
 
     console.log(_this.innerHTML) 
 
     }, 
 
     testFunc2: function() { 
 
     console.log(_this) 
 
     } 
 
    } 
 
    } 
 
}); 
 
var span = document.getElementById('mySpan'); 
 

 
span.testNS.testFunc(); 
 
span.testNS.testFunc2();
<span id="mySpan">Wah-hoo!</span>

より「バニラ」アプローチtestNSを単純な関数にして、それを1のように呼び出すことです。

HTMLSpanElement.prototype.testNS = function() { 
 
    var _this = this; 
 
    return { 
 
    testFunc: function() { 
 
     console.log(_this.innerHTML) 
 
    }, 
 
    testFunc2: function() { 
 
     console.log(_this) 
 
    } 
 
    } 
 
} 
 

 
var span = document.getElementById('mySpan'); 
 

 
span.testNS().testFunc(); 
 
span.testNS().testFunc2();
<span id="mySpan">Wah-hoo!</span>

+0

HeyはObject.create()を使用してこれを行うことができます –

+0

@AnkitPandey私はあなたが何を求めているのか分かりません。 – JLRishe

+0

実際に私は{testFunc:function()...}を入れたいHTMLSpanElement.prototype.testNS = Object.create()のようにしようとしています –

0

私が
:-)同等の奇妙なソリューションは基本的にはcreateElementリテラル名前空間のオブジェクトを追加し、インスタンスを使用して、名前空間の上に新しい機能testFuncを定義するためにオーバーライドされた奇妙な要件書いていますのであなたはfoo.bar()としての機能を呼び出すときに機能

!function(){ 
    var defaultNamespace = "testNS"; 
    var createElement = document.createElement; 

    document.createElement = function(tag, namespace) { 
     var element = createElement.apply(document, arguments); 

     element[namespace || defaultNamespace] = { 
      testFunc : function() { 
       console.log(this.innerHTML); 
      }.bind(element) 
     }; 

     return element; 
    }  
}(); 

var span = document.createElement("span"); 
+0

少し奇妙ですが、私は何よりも好奇心が強い、私はjavascriptのスコープについてもっと学びようとしています。 – Krum110487

1

にバインドさ元素から、その後bar内部thisfooを指します。したがって、関数をspanElement.testNS.testFunc()と呼び出す場合は、はspanElement.testNSを指します。

_this: this,this<span>要素を参照できないため機能しません。

あなたはゲッターとしてtestNSを実装することができtestFuncからspanElementへのアクセスを取得するには、次の

Object.defineProperty(HTMLSpanElement.prototype, 'testNS', { 
 
    get: function() { 
 
    var element = this; 
 
    return { 
 
     testFunc: function() { 
 
     console.log(element.innerHTML); 
 
     }, 
 
    }; 
 
    }, 
 
}); 
 

 
document.querySelector('span').testNS.testFunc();
<span>foo</span>

関連する問題