EDITORIAL
記事のこのシリーズは、ただ単に読むことを学んでいるときに感じ始める、ブックまとめたものでは来る「JavaScriptのデザインパターン」の研究を介して行われ、後でメモを取る、それだけにはもはや必要はコンテンツの一部を理解するために本を見つけないと〜批判と共通の進歩、お願い本はビットおよびそれのノートからも、ソート、自分の理解に関連して説明されるので、非常に簡単ではありません、と私たちは私が正しく内容を理解している場合、一緒に記事を学ぶことを願っています
ディレクトリ
コンテンツ
この基本的な知識
私たちが最も不可解で、これは、異なる言語の多くで、これはJSで常にある、ということです学ぶときJSオブジェクトにあるが、これは、この関数のポイントは、オブジェクト定義や時に定義されていません我々はプログラムを実行するとOKが、それは動的バインディングです。ここでは、この点に最も一般的なシナリオのいくつかを見てみましょうです。
図1に示すように、オブジェクトのメソッド呼び出しなどの機能が
我々は「)(obj.code」など、オブジェクトのメソッドとしてこれを関数を呼び出しますならば、我々は、コードを書くとき、私たちは、これは常に、このオブジェクトを指し示すされていますされているこの時間は、我々は次の一節を見てコード:
var objectone = {
name: 'xbeichen.cn',
getName: function () {
console.log(this === objectone);
console.log(this.name);
}
};
objectone.getName();
上から見ることができ、私たちのgetName関数はメソッドのobjectoneオブジェクトである、8行目に、私たちはobjectone.getName(でこの関数を呼び出す)、上記の目的をobjectoneする結合このダイナミックの内側に機能、私たちは、上の図の結果を得ました。
通常の関数呼び出しとして2、機能
我々は唯一の通常の関数呼び出しとして機能するほとんどの場合、この時間は、これはグローバルオブジェクトの内側に私たちのブラウザJSのデフォルトグローバルオブジェクトへのポインタであるデフォルトウィンドウオブジェクトであるが、この場合ES5の厳しいです通常の関数呼び出しとしてES5 strictモード機能では、この規定は、グローバルオブジェクトへの我々のポイントではありませんが、ポイントは未定義ときモードは、あまり正確です。以下の2つのケースを見てください:
普通のシーン:
window.name = "xbeichen.cn";
var getName = function () {
return this.name;
};
console.log(getName());
//或者这样
var objecttwo = {
name: "test",
getName: function () {
return this.name;
}
};
var getNameNew = objecttwo.getName;
console.log(getNameNew());
あなたが見ることができるコードの2枚以上、コードの私たちの最初の部分はよく理解されている、のgetName()このポイントの関数の内部には、デフォルトのグローバルオブジェクトウィンドウに、通常の関数として呼び出され、私たちが最初に定義されているコードの2番目の段落オブジェクトは、このオブジェクトはまた、我々はとき、実際には、で、getNameNew、この変数は、メソッド内のオブジェクトを呼び出すために、変数に、このオブジェクトのgetName()メソッドのアドレスを引用しようとしている、name属性を持っています私たちは、上記の出力画像を見るように、呼び出しに通常の関数の形で、ので、ここでこれはまだ、グローバルwindowオブジェクトを指しています。
我々は、書き込みに上記のコードES5 strictモードを使用する場合は、次のシナリオのようになります。
strictモードシーン:
"use strict"
window.name = "xbeichen.cn";
var getName = function () {
return this.name;
};
console.log(getName());
//或者这样
var objecttwo = {
name: "test",
getName: function () {
return this.name;
}
};
var getNameNew = objecttwo.getName;
console.log(getNameNew());
コードはES5のstrictモードで実行され、我々はそれが理由です、この「名前」属性を見つけましたが、はっきりとコード属性はウィンドウオブジェクトああの名前を指定することをお勧めていなかったと言って、実行を与えられて最終結果を見ることができます?その理由は、我々はウィンドウオブジェクトのname属性を定義しているので、にもかかわらず通常の関数として、この関数呼び出しの内部にあるES5 strictモードで、デフォルトのウィンドウオブジェクトに、もはやポイントの未定義の点で、前にも言ったが、しているということですまだそれは、それが実行されて文句を言うでしょう。ためにはより明確に私たちが見て、その後、次のコードを実行してみましょう、実行時にこのポイントの最後でこれを参照してください。
"use strict"
window.name = "xbeichen.cn";
var getName = function () {
return this;
};
console.log(getName());
//或者这样
var objecttwo = {
name: "test",
getName: function () {
return this;
}
};
var getNameNew = objecttwo.getName;
console.log(getNameNew());
上記のコードでは、我々は、この時間は、我々はエラーコードではありません、そして最終的に私たちの言っ検証する、未定義に戻り、元のコード関数は値が、それは単にこれを返し修正前:ES5のstrictモードで次は、関数がその内部に通常の関数として呼び出されたときに未定義この時点で、デフォルトのウィンドウオブジェクトにはもはやポイントです。
私たちは、多くの場合、状況に遭遇するシーンで、通常の関数呼び出しとして機能:DOMノードのイベント内では、地元の機能を有しており、地元の機能として、この時間は、通常の関数呼び出しであるが、それは、このウィンドウの内側を指すが、我々元の意志が、それは、DOMノードにこの点の内側です。上記課題を解決するために、我々は以下のコードを見て:
オリジナルコード:
<body>
<div id="xbeichen">
click me
</div>
<script>
window.id = "xbeichen.cn";
document.getElementById("xbeichen").onclick = function () {
console.log(this.id);
var currentCallback = function () {
console.log(this.id);
};
currentCallback();
}
</script>
</body>
コードが動作し、結果を見ることができます)、私たちはイベントのdivノードをクリックして、あなたは、このコマンドの出力を最初に実行するときには、これは私たちの考えと一致している私たちのDOMノードへのポインタですが、ローカル関数で(イベントをクリックしcurrentCallbackこの点は、私たちが最も典型的なJS「この損失」状況を開発した理由である私たちの本来の意図に反しウィンドウ、でした。次に、どのように我々はこの問題を解決することができ、次のように、実際には、非常に単純な、変更する場合は、この時点でローカル関数以来、我々はOKを修正するためのポイントに戻ってそれを渡しますんので、変更されたコードは次のようになります。
最適化されたコードの後:
<body>
<div id="xbeichen">
click me
</div>
<script>
window.id = "xbeichen.cn";
document.getElementById("xbeichen").onclick = function () {
var _self = this;
console.log(this.id);
var currentCallback = function () {
console.log(_self.id);
};
currentCallback();
}
</script>
</body>
最適化されたコードの上に見ることができ、実際に、私たちは「_selfがこれを= VAR;」増加し、このコード行を、私たちの役割は、あなたがバインドどんな後、上記のカスタム変数_selfで、この結合事象の内側をクリックすることですこの点は、常にDOMノードとなっているに限り_self変数がこれを得るために、我々が得る、どのように多くの層のローカル関数の中にネストされたイベントをクリックします。
3、コンストラクタの呼び出し
誰もいない、我々はその中のすべてのオブジェクトは、プロトタイプからのコピーに基づいており、JSクラスから知っているが、我々はあなたがオブジェクトは、そのような文言のルックスを作成するためにコンストラクタとnew演算子を使用することができ、エンコードされていますまた、クラスのコンストラクタのように。既存のコンストラクタに加えて、我々はほとんどの機能はまったく同じに見えるかもしれコンストラクタ、コンストラクタ関数と通常の関数として使用することができますJS、JSのホストを提供する、唯一の違いは、彼らの呼び出しです実施形態では、コンストラクタ関数は、new演算子によって呼び出されます。
オブジェクトを作成するコンストラクタ関数への呼び出しは、我々コンストラクタ関数は常にオブジェクトを返すと、通常、我々は、返されるオブジェクトは、次のコードに、このポイントというコンストラクタ内で機能します:
var myBlog = function () {
this.url = "http://www.xbeichen.cn";
};
var blogone = new myBlog();
console.log(blogone.url);
私たちの上に特殊な状況下で、それが何であると、通常の状況下では、この時点内部コンストラクタは、このオブジェクトを返すようにする場合、コンストラクタを使用してオブジェクトを作成し、言いましたか?我々はコンストラクタでオブジェクトを作成する場合は、コンストラクタを明示的に、我々は、オブジェクトが返されたで終わる、オブジェクトを返しますが、ではない。このことを楽しみにして前に、次のコード:
var myBlog = function () {
this.url = "http://www.xbeichen.cn";
return {
url: "http://www.geov.online"
}
};
var blogone = new myBlog();
console.log(blogone.url);
コードは設定が明示的である我々は、明示的に定義されていないオブジェクトコンストラクタ返さurl属性のurl url属性プロパティを受け、この時点で、オブジェクトを返しますが、構造がない場合は、見ることができます以下のように明示的な戻りオブジェクトは、それが非表示のデータオブジェクト型を返す場合でも、上記のケースが発生することはありません。
var myBlog = function () {
this.url = "http://www.xbeichen.cn";
return "http://www.geov.online";
};
var blogone = new myBlog();
console.log(blogone.url);
4、Function.prototype.call和Function.prototype.applyの
前の3例と比較して、より多くのFunction.prototype.call Function.prototype.applyのは、より多くの知識の意志、コードでの外観を理解することは簡単です聞かせて機能この時点問題に渡さ上記の変更を使用することです後半に詳細を実行します。
var myBlog1 = {
url: "http://www.xbeichen.cn",
getUrl: function () {
return this.url;
}
};
var myBlog2 = {
url: "https://xuqwblog.blog.csdn.net/"
};
console.log(myBlog1.getUrl());
console.log(myBlog1.getUrl.call(myBlog2));
コードによって見ることができる、我々は2つのオブジェクトを定義し、結果は書き込みの通常モードに応じて、我々はまた、所望の結果が得られた出力文の最初の行であるが、2番目のステートメントは、我々は、動的に()メソッドを呼び出しますこの時点myBlog1にバインドされたオブジェクトを変更し、それは、myBlog2変更オブジェクトに関連付けされますので、上記の目的のurl属性の出力2。
4上記の場合、我々は上記の4つのシーンに加えて、この点をエンコードするときと同様に、あまり一般的とevalのシーンとして、ここでは紹介されていない、現場に最も共通している、我々は興味を持っているが、所有することができます毎日の数はあまりないの開発に発生したためBaiduは、次のを理解しています。
この損失の問題
私たちは、上記のコード部分を見てみましょう。
var objecttwo = {
name: "test",
getName: function () {
return this.name;
}
};
console.log(objecttwo.getName());
var getNameNew = objecttwo.getName;
console.log(getNameNew());
コードは、上記から分かるように、出力文のname属性の最初の行我々の通常の出力、出力文NULL値の第二の出力線、これは、オブジェクトのメソッドとして最初のライン出力ステートメントのgetName()関数コールので、これはオブジェクトobjecttwo点であり、第二の出力線、ここでgetNameNew()関数もポインタアドレスobjecttwo.getNameであるが、最終的にそれが機能は、通常の方法によって呼び出されるので、出力文がnullこれは、ここでグローバルwindowオブジェクトにデフォルトのポイントであるので、我々はstrictモードを使用し、ここならば、NULL値の出力は、その後、出力文の2行目は以下のように与えられます。
ここでのグローバルwindowオブジェクトは、我々はそのname属性を指定しなかったためです。その後、我々は別のシナリオを見て、例1のこの損失です。
私たちの上に特定のDOMノードのために、このようなアプローチをエンコードするときに、非常に複雑になるというのdivの「xbeichen」のIDを取得するには、ネイティブJS文言「のdocument.getElementById(」xbeichenを「)」を使用したときに、我々このようなAフレームワークprototype.jsの練習として使用することができ、次のように略記します。
var getId = function (id) {
return document.getElementById(id);
};
getId("xbeichen");
それ以来、フォローアッププロセスの特定のDOMノードを得るために、我々は単にこれにのgetId()メソッドを呼び出して、私たちは別の単純な文言を検討することを望むかもしれないことを、ずっと簡単:
var getId = document.getElementById;
getId("xbeichen");
上記の文言は、prototype.jsのにこのフレームワーク、ネイティブのJSは、DOMノードの動作を得る簡素化するためのコードは1行だけを書くよりも簡単ですが、私たちは、これが理由であるとき、ブラウザで実行するために文句を言うのだろうか?我々はgetElementByIdを()メソッドを持っていた場合は、このドキュメントの機能は、これを使用している、それを呼び出すことですので、この時点でこれはとてもネイティブ特定のDOMによって書き込まれますオブジェクトへの文書のポイントは、取得することが可能ですが、私たちのように上記のコード、のdocument.getElementByIdのgetId変数と参照アドレス、その後のgetId(呼び出す)この関数は、それが通常の関数コールとなった場合、今回内部関数がもはやドキュメントオブジェクトを指し、代わりのを指していますデフォルトのウィンドウオブジェクトなので、このようなA文言エラー。次に我々は、我々のコードの下でそれを修正し、動的にこの点を変更するには()メソッドを適用するために導入の上部を使用して、以下のように、コードは次のとおりです。
<div id="xbeichen"></div>
<script>
document.getElementById = (function (func) {
return function () {
return func.apply(document, arguments);
}
})(document.getElementById);
var getId = document.getElementById;
console.log(getId("xbeichen"));
</script>
これらは、この損失のイベントのローカル関数の前に2つの損失の最も一般的な問題に加えて、DOMノードが、この損失は、この損失の状況とソリューションは遅刻になり、より詳細に3つの問題を導入している私はAを整理別の記事を紹介し、楽しみにして楽しみます。
そして、コールの基本を適用します
Function.prototype.callとES3 Function.prototype.applyの実際の機能コードの開発プロセスへの書き込みのこれらの2つの方法の関数のプロトタイプを定義された2つの方法から始めた二つの方法は、デザインやJSに特に有用ですモードは、2つの方法の非常に重要かつ広範囲に使用されます。コールの2つの方法との役割は異なる引数がそれを通過しただけで、まったく同じ適用されます。
適用呼ばにパラメータとして渡されている方法は、体内の機能を指定するために2つのパラメータ、この時点の最初のパラメーターを取り、2番目のパラメータはアレイまたはアレイ型であり、これは、コレクション又はアレイエレメントの方法を適用します機能。
呼び出し方法は、最初のパラメータは、この関数内のポイントを指定するために使用されるが、順次、関数に渡された第2のパラメータから開始され、2つのパラメータを受け付けます。パラメータの数がメソッドの呼び出しに渡されて固定されていない、我々は関数がパラメータを受け入れ、一目で正式なと実際のパラメータとの対応を表現したい、ということどのように多くのを知っていれば、それは、より多くの方法を適用の上にシンタックスシュガーのようなものです私たちは、パラメータを渡すためのメソッドを呼び出すことができます。私たちはどのように多くの特定のパラメータを気にしないならば、我々はそれにしてプッシュするために落ちる関数にパラメータを適用するためにメソッドを使用します。私たちは、コードの具体的な例を見てみましょう:
適用方法には、デモ:
var testfunc = function (a, b, c) {
console.log([a, b, c]);
};
testfunc.apply(null, [1, 3, 2]);
コールプレゼンテーション方法:
var testfunc = function (a, b, c) {
console.log([a, b, c]);
};
testfunc.call(null, 1, 9, 7);
コードの最初の部分では、我々は、適用方法testFunc()関数、三つの値の関数パラメータ、Bにそれぞれ対応のアレイ、C 3から渡された配列に3つの数字を配置しましたパラメータ。最初のコードパラメーターを実行し、アレイ内のJSパラメータが表されるので、我々はこの方法を適用すると言うことができるように、数、タイプ及び引数の順序の差よりも占めないJSインタプリタメソッドの呼び出しよりも高い利用率。
コードの2枚以上のように、我々は、メソッドとコールを使用しているとき、我々は最初の引数がnullで渡すと、それがある場合は、デフォルトのホスト・オブジェクトを指します。この関数の本体は、ブラウザは、ウィンドウオブジェクトで適用されます次のようにES5厳密モードでは、この点は、ヌルです。
ブラウザ環境:
var testfunc = function (a, b, c) {
console.log(this === window);
};
testfunc.call(null, 1, 9, 7);
strictモード:
var testfunc = function (a, b, c) {
"use strict"
console.log(this);
};
testfunc.call(null, 1, 9, 7);
これらが適用され、呼び出し方法、使用するには、2つの方法が何であるかで見てみましょうするための基本的な紹介です。
適用及び使用を呼び出します
上述したように、適用および使用の呼び出し方法は、JSのデザイン内部パターン、およびこれらの2つの方法で特に普及しているが、関数型プログラミングでは特に重要であり、彼らはそれが何であるか、使用終了しているという点で、私は上へ、次、次の三つの用途をまとめました詳細の下、様々な使用シナリオ。
変更するには、このポイントの1、
上述したように、適用および最も広く使用されているメソッド呼び出しを動的にポイントするために使用されるように、次のコードに示すように、この本体の関数として変化します。
window.url = "http://www.geov.online";
var myblog1 = {
url: "http://www.xbeichen.cn"
};
var myblog2 = {
url: "https://xuqwblog.blog.csdn.net/"
};
var getUrl = function() {
console.log(this.url);
};
getUrl();
getUrl.apply(myblog1);
getUrl.apply(myblog2);
このウィンドウオブジェクトにデフォルト、URL属性ウィンドウオブジェクトの出力インビボで上記のコードのgetURL()関数の一般的な通話機能が、使用方法はのgetURL()関数は、この点の体の機能を起動している適用されています動的myblog1とmyblog2オブジェクト、二つの出力URLオブジェクトの最終的な特性に結合します。
この変更されたシナリオで、我々は2が言及した上で、我々は多くの場合、開発中に遭遇する:まず、イベントのDOMノードに、ローカル関数のこの時点で、デフォルトのウィンドウオブジェクトに変更されます。2 document.getElementByIdは、シーンに、このポイントの補正です。
イベントのDOMノード、この変更されたシナリオで、我々は、変数_selfの、すなわち定義を解決するために、最も単純なアプローチを使用しているローカルの内部機能について、DOMノードへの参照を保存するためにそれを使用。次のようにここでは、解決するか、呼び出しに同じアプローチを適用することができます。
<body>
<div id="xbeichen">
click me
</div>
<script>
window.id = "xbeichen.cn";
document.getElementById("xbeichen").onclick = function () {
//var _self = this;
console.log(this.id);
var currentCallback = function () {
console.log(this.id);
};
currentCallback.call(this);
}
</script>
</body>
document.getElementByIdは速記解決する方法を適用し、この変更されたシナリオの方法により、以下のような場合、上記のDOMノードイベント、ローカル内部関数この変更されたシナリオに加えて、我々はまた、発生しました:
document.getElementById = (function (func) {
return function () {
return func.apply(document, arguments);
}
})(document.getElementById);
var getId = document.getElementById;
console.log(getId("xbeichen"));
2、Function.prototype.bind
ほとんどのブラウザでは、内蔵されている方法Function.prototype.bindを達成するために、この点を結合するために使用、次のようにコードは次のとおりです。
var myblog1 = {
url: "http://www.xbeichen.cn"
};
var getUrl = function () {
console.log(this.url);
}.bind(myblog1);
getUrl();
バインド()メソッドによって、この点を結合するためのコードは、最終的な出力は、URL属性myblog1オブジェクトです。あなたは、この点をバインドするために結合しない場合は、このウィンドウのグローバルオブジェクト内部のデフォルトへのポインタである通常の関数呼び出し、など私たちのgetURL()関数。
しかし、ブラウザのいくつかの低いバージョンでは、我々はバインドバインドには、このメソッドを使用したい文句を言う場合は、次のように、この時間は、我々は、この方法の簡易版独自のバインドを書くことができ、Function.prototype.bindメソッドを実装されていません。
Function.prototype.bind = function( context ){
var self = this; // 保存原函数
return function(){ // 返回一个新的函数
return self.apply( context, arguments ); // 执行新的函数的时候,会把之前传入的 context
// 当作新函数体内的 this
}
};
var obj = {
name: 'sven'
};
var func = function(){
alert ( this.name ); // 输出:sven
}.bind( obj);
func();
上記のコードでは、私たちは「パッケージ」のfunc関数にFunction.prototype.bindていると、パラメータコンテキストとしてオブジェクトを渡し、コンテキストは、私たちは、このオブジェクトのオブジェクトを改正したいということです。
内部Function.prototype.bindは、我々は保存された関数funcへの参照を入れ、その後、新しい関数を返します。我々は将来的に関数funcを実行すると、実際には、それだけで返されたこの新機能の最初の実装です。このコードの新しい機能、self.apply(コンテキスト、引数)内の元のFUNC機能を実行し、この本体FUNC機能のコンテキストオブジェクトを指定します。
3、他のオブジェクトのメソッドを借ります
適用し、二種以上を使用する以外の方法を呼び出し、他のオブジェクトから借用された第三の目的があります。ここをご紹介する2つのシナリオに分けられます。
コンストラクタを借りる3.1、
この方法は、シナリオを借りオブジェクトはコンストラクタで、この技術によって、我々は以下のコードを見て一緒に継承されたいくつかの同様の効果を得ることができます借りました。
var myblog1 = function (url) {
this.url = url;
};
var myblog2 = function () {
myblog1.apply(this, arguments);
};
myblog2.prototype.getUrl = function () {
return this.url;
};
var testblog = new myblog2("http://www.xbeichen.cn");
console.log(testblog.url);
パラメータリストの引数3.2、操作機能
引数配列オブジェクト内の関数のパラメータのJSリストはクラスで、それはまた、より低い基準を持っていますが、我々は、ソート、それが直接、またはそのような操作などの新しい要素を追加することはできませんので、それは、すべての後に実際の配列ではありません。今回は、たとえば、引数を操作するオブジェクトにArray.prototypeをメソッドを借りる必要があります。我々は、引数に新しい要素を追加したい場合は、以下のように、あなたは、Array.prototypeをオブジェクトプッシュ()メソッドを借りることができます。
(function () {
Array.prototype.push.call(arguments, 3);
console.log(arguments);
})(1, 2);
実際の開発プロセスでは、実際には、我々はときにオブジェクトArray.prototypeを借りに非常に頻繁にメソッドの引数を操作したい場合。Array.prototype.pushメソッドを借りたときに任意のオブジェクトを借りることはできませんが、オブジェクトのボローArray.prototype.push方法は、以下の2つの要件を満たす必要があります。
- オブジェクト自体に属性にアクセスすることができます。
- 長さは、読み書き可能オブジェクトのプロパティを。
これらのメソッドが呼び出すと、第一及び第三の最も一般的に、実際に現在開発中の最も一般的な3つの使用を適用し、第二のブラウザのいくつかの下のバージョンは、バインドメソッドが導入されたサポートしていません考慮することがあるです。
概要
この記事では、第一章「JavaScriptのオブジェクト指向、」レビューに基づいての記事では、これらの2件の記事を、私たちはこの、呼び出し、中にどのようなオブジェクト指向のJS見直さ簡単に持っているもう一つの知識ポイントで、適用されますこれらの知識は、その後、我々は最終的にJSの閉鎖や高階関数は、いくつかの知識の見直しを行い、我々はその後、JSのデザインパターンは、旅を学び始めたという記事があります。