私は、この特定の動作を理解するために深く掘って私は良い説明を見つけたと思います。
document.getElementById
のエイリアスにならないうちに、JavaScript関数/オブジェクトの動作を説明します。
JavaScript関数を呼び出すたびに、JavaScriptインタプリタはスコープを決定し、それを関数に渡します。
は、関数を次の点を考慮
function sum(a, b)
{
return a + b;
}
sum(10, 20); // returns 30;
この関数は、ウィンドウのスコープで宣言され、あなたがそれを呼び出すときsum関数の内部this
の値は、グローバルWindow
対象となります。
'sum'関数の場合、 'this'の値が使用されていないため、その値は関係ありません。
機能を、次の点を考慮:あなたはdave.getAge関数を呼び出すとき
function Person(birthDate)
{
this.birthDate = birthDate;
this.getAge = function() { return new Date().getFullYear() - this.birthDate.getFullYear(); };
}
var dave = new Person(new Date(1909, 1, 1));
dave.getAge(); //returns 100.
、JavaScriptインタープリタを使用すると、dave
オブジェクト上getAge関数を呼び出していることを見ているので、this
dave
にを設定して呼び出し、 getAge
機能。 getAge()
は正しく100
を返します。
JavaScriptでapply
メソッドを使用してスコープを指定できることがわかります。それを試してみましょう。上記の行で
var dave = new Person(new Date(1909, 1, 1)); //Age 100 in 2009
var bob = new Person(new Date(1809, 1, 1)); //Age 200 in 2009
dave.getAge.apply(bob); //returns 200.
、代わりにJavaScriptが有効範囲を決定させるのは、bob
オブジェクトとして手動でスコープを渡しています。 getAge
はdave
オブジェクトでgetAge
を呼び出したと思っても200
を返します。
上記のすべてのポイントは何ですか?関数はJavaScriptオブジェクトに「疎結合」されています。例えば。あなたはのは、次のステップを見てみましょう
var dave = new Person(new Date(1909, 1, 1));
var bob = new Person(new Date(1809, 1, 1));
bob.getAge = function() { return -1; };
bob.getAge(); //returns -1
dave.getAge(); //returns 100
を行うことができます。
var dave = new Person(new Date(1909, 1, 1));
var ageMethod = dave.getAge;
dave.getAge(); //returns 100;
ageMethod(); //returns ?????
ageMethod
実行時にエラーが発生します。何が起こった?あなたは慎重に私のような点を読めば
は、JavaScriptがageMethod
実行のための「スコープ」を決めることができなかったのに対し、dave.getAge
方法がdave
this
としてオブジェクトと呼ばれたことに注意します。それで、グローバルな「ウィンドウ」を「this」として渡しました。現在window
にはbirthDate
プロパティがないため、ageMethod
の実行は失敗します。
これを修正するにはどうすればよいですか?シンプル、
ageMethod.apply(dave); //returns 100.
上記メイク感覚のすべてをしましたか?それがない場合は、エイリアスdocument.getElementById
にできない理由を説明することができるようになります:
var $ = document.getElementById;
$('someElement');
$
this
としてwindow
と呼ばれ、getElementById
実装はthis
はdocument
であることを期待している場合、それは失敗します。
再びこの問題を解決するために、あなたがそう
$.apply(document, ['someElement']);
を行うことができますなぜそれがInternet Explorerで動作しますか?
私はgetElementById
のIEでの内部実装はわかりませんが、jQueryソース(inArray
メソッド実装)のコメントでは、IEではwindow == document
と表示されています。その場合、エイリアスでdocument.getElementById
のエイリアシングが機能するはずです。
これをさらに説明するために、私は精巧な例を作成しました。下記のPerson
関数を見てください。上記Person
機能については
function Person(birthDate)
{
var self = this;
this.birthDate = birthDate;
this.getAge = function()
{
//Let's make sure that getAge method was invoked
//with an object which was constructed from our Person function.
if(this.constructor == Person)
return new Date().getFullYear() - this.birthDate.getFullYear();
else
return -1;
};
//Smarter version of getAge function, it will always refer to the object
//it was created with.
this.getAgeSmarter = function()
{
return self.getAge();
};
//Smartest version of getAge function.
//It will try to use the most appropriate scope.
this.getAgeSmartest = function()
{
var scope = this.constructor == Person ? this : self;
return scope.getAge();
};
}
、ここでは様々なgetAge
方法がどのように動作するかです。
Person
機能を使用して2つのオブジェクトを作成しましょう。
var yogi = new Person(new Date(1909, 1,1)); //Age is 100
var anotherYogi = new Person(new Date(1809, 1, 1)); //Age is 200
console.log(yogi.getAge()); //Output: 100.
ストレートフォワード、getAge方法はthis
出力100
としてyogi
オブジェクトを取得します。 this
としてwindow
オブジェクトを設定し、私たちのgetAge
方法は-1
を返しますinterepreter
var ageAlias = yogi.getAge;
console.log(ageAlias()); //Output: -1
JavaScriptを。
console.log(ageAlias.apply(yogi)); //Output: 100
我々は正しい範囲を設定する場合は、ageAlias
メソッドを使用することができます。
console.log(ageAlias.apply(anotherYogi)); //Output: 200
我々はいくつかの他の人物オブジェクトに渡すと、それはまだ正確に年齢を計算します。あなたは正しいスコープを供給心配する必要はありません、今ので
var ageSmarterAlias = yogi.getAgeSmarter;
console.log(ageSmarterAlias()); //Output: 100
ageSmarter
機能は、元this
オブジェクトを捕獲しました。
console.log(ageSmarterAlias.apply(anotherYogi)); //Output: 100 !!!
ageSmarter
の問題は、あなたには、いくつかの他のオブジェクトに適用範囲を設定することはできませんということです。
var ageSmartestAlias = yogi.getAgeSmartest;
console.log(ageSmartestAlias()); //Output: 100
console.log(ageSmartestAlias.apply(document)); //Output: 100
無効な範囲が供給された場合ageSmartest
関数は、元のスコープを使用します。
console.log(ageSmartestAlias.apply(anotherYogi)); //Output: 200
あなたはまだgetAgeSmartest
に別のPerson
オブジェクトを渡すことができるようになります。 :)
- それは魔法の関数か何かのいくつかの種類である可能性があります。 –
http://stackoverflow.com/questions/954417で誤った回答にコメントを追加し、ここで指示しました。 –
Function.prototype.bindメソッドをサポートするブラウザーの場合:window.myAlias = document.getElementById.bind(document); MDNドキュメントを検索すると、バインドシムが存在します。 –