ホームページ >ウェブフロントエンド >jsチュートリアル >JSの重要な知識ポイントまとめ_JavaScriptスキル

JSの重要な知識ポイントまとめ_JavaScriptスキル

WBOY
WBOYオリジナル
2016-05-16 17:59:321054ブラウズ

説明はまだコメント付きのサンプル コードの形式です。ここに小さなディレクトリがあります。
JS コードの事前解析原理 (3 つの段落を含む)
関数関連 (関数パラメータの転送、関数のメソッドの呼び出しを含む)。パラメータ、クロージャ パッケージ);
オブジェクト指向 (オブジェクトの作成、プロトタイプ チェーン、データ型の検出、継承を含む)。
JS コードの事前解析原理

コードをコピー コードは次のとおりです:

/****************** JS コード事前解析の原理 ********************/
/*
JS コードの事前解析、変数スコープ、スコープ チェーンなどは、JS 言語を学習するための入門知識として使用してください。
簡単な説明といくつかの典型的なコード スニペットを以下に示します。さらに詳しく知りたい場合は、インターネットでさらに関連する例を検索してください。
「JS の実行順序」についてのインターネットの説明を引用します:
ドキュメント フローに複数のスクリプト コード セグメント (スクリプト タグで区切られた JS コード、または導入された JS ファイル) が含まれる場合、その実行順序は次のとおりです:
ステップ 1. 最初のコードセグメントを読み取ります (js 実行エンジンはプログラムを 1 行ずつ実行するのではなく、部分ごとに分析して実行します)
ステップ 2. 構文分析を実行し、エラーがある場合は構文エラーを報告します。 (括弧の不一致など)、ステップ 5 にジャンプします
ステップ 3. var 変数と関数定義の「事前解析」を実行します (正しい宣言のみが解析されるため、エラーは報告されません)
ステップ 4. コード セグメントを実行し、エラーがある場合はエラーを報告します (変数が未定義であるなど)
ステップ 5. 別のコード セグメントがある場合は、次のコード セグメントを読み取り、ステップ 2 を繰り返します
ステップ 6. 終了
*/
// ここでは、比較的典型的だと思われる 3 つのコード例を示します。 🎜>var num = 0;
alert(str); // エラー: str が未定義です
str = "string";
alert(func); // 未定義
var func; ){alert('exec func '); }
test(); // テストを実行し、次に未定義の関数 test()を実行します。 '実行テスト'); }
/********** 1: 基本的なステートメント **********/
//var mark = 1;
関数 mark(x) {
return x * 2; 🎜>var mark;
alert(mark); // function mark(x) { return x * 2; }
// 前の var mark = 1 を削除すると 1 が返されます。 ********* 2: 関数名は変数名と同じです **********/
// 条件がある場合(コードが条件文ブロックに含まれる)
if (false) {
var mark1 = 1;
function mark1() {
alert("exec mark1");
//var mark1)
}
alert(mark1); ;
// 解析ブラウザーが異なるため、このコードを異なるブラウザーで実行した結果は一貫性がありません。


関数関連 (関数パラメーターの転送、呼び出しを含む) はオンラインで確認できます。パラメーター付き関数のメソッド、クロージャー)




コードをコピー


コードは次のとおりです:

/****************** 機能関連 **********************/
/********** 1: 関数パラメータ転送 **********/
/*
プログラミング言語には一般に値型と参照型の違いがあり、JS は例外はありません。
元の型: 未定義の null 数値、ブール型はすべて値型です。
String は不変であるため特別であり、String クラスで定義されたメソッドはいずれも文字列の内容を変更できません。
関数オブジェクト配列 これら 3 つの型は参照型です。
*/
/* JavaScript 関数がパラメーターを渡す場合、値によって渡されます。
ECMAScript では、すべての関数パラメータは値によって渡されます。
基本型の値の転送は、基本型変数のコピーと一致します (新しい値はスタック上に作成されます)。
参照型の値の転送は、参照のコピーと一致します。型変数 (ポインタはスタックに格納され、ヒープ内の同じ値を指します) オブジェクト)。
具体的な参考資料: http://www.xiaoxiaozi.com/2010/03/05/1719/
*/
function setName(obj){
//obj は person の値をコピーします ( person はオブジェクトの参照アドレスです)、したがって、obj も person が指すオブジェクトを指します。
obj.name = "xiaoxiaozi";
obj = {}; // obj が別のオブジェクトを指すようにします
obj.name = "admin";
var person = { } ;
setName(person);
alert(person.name); // xiaoxiaozi
/********** 2: パラメータを指定して関数を呼び出す方法 **********/
/* 異なるバージョンの DOM では、関数呼び出しメソッドは次のようになります。違う 同じ。標準的な推奨事項は、addEventListener とattachEvent です。
これら 2 つのメソッドについては、多くの情報が入手可能です。ただし、推奨されなくなった一部の関数呼び出しにはまだ実用的な用途があり、関連する情報はあまり見つかりません。
ここでは主にこれらの関数呼び出しメソッドについて説明します
*/
var g = "グローバル変数";
function show(str) {
alert("my site: " str); 🎜 >}
setTimeout("show(g);",100); // g はグローバル変数であり、関数は正しく実行されます
function t() {
var url = "www.xjiwei .cn";
var num = 2;
//setTimeout("alert(" url ")", 3000); // 解析エラー、www は未定義です
//setTimeout("alert(" num ")" , 3000); // 解析は正しいので、前の文と比較してください
//setTimeout("show('url');", 2000); // url
//setTimeout ("show(" url " );", 2000) // 解析エラー、www が定義されていません
//setTimeout("show(url);", 2000); // 解析エラー、URL が定義されていません
//setTimeout('" show(" url ");"', 2000); // 解析エラー、URL が未定義です
//setTimeout("show('" url ");", 2000 ); // 正しい
/ /setTimeout(function(){show(url);},1000) // 正しい
}
/* 結論:
onclick="xx();" など、他の関数呼び出しメソッドでは、二重引用符内の内容が実行のために js ステートメントに直接解析されます。
呼び出される関数にパラメータがある場合は、上記のさまざまな記述方法を比較して、渡されたパラメータが正しいことを確認することに注意してください。
*/
/********** 3: 終了 **********/
/*
Closure は、JS を勉強している友達ならほぼ全員が議論する問題なので、関連する情報はあらゆる種類があります。
これは非常に便利ですが、欠点もあります。たとえば、不適切に使用すると、メモリ リークやその他の問題が発生しやすくなります。そのため、多くの人は
クロージャの使用を減らすことを推奨しています。
これはクロージャの古典的な応用例であり、物議を醸している応用例です。
*/
function test1() { //クロージャを通じて、毎回異なる j 値を渡すことができます。
for (var j = 0; j (function (j) {
setTimeout(function () {alert(j) }, 3000);
}) (j);
}
}
test1();
/* これはクロージャの典型的な適用です*/
(function tt() {
for (var i = 1; i < 4; i ) {
document.getElementById("b" i).attachEvent("onclick",
new Function("これはボタンです' i '");' ); // IE でテスト
}
})() // 関数をすぐに実行します。ファイルごとに 1 つだけ実行できますか?上記の関数をすぐに実行するように記述すると何が問題になるのでしょうか?
/* この質問はフォーラムに登場し、多くの議論がありました。
new Function はクロージャー構造を持つ関数を動的に生成するため、外部変数を保存できると言われています。
New Function は新しく定義された関数です。
この新しい関数のパラメータとして i の値も内部に固定されています。
*/


オブジェクト指向 (オブジェクトの作成、プロトタイプチェーン、データ型検出、継承を含む)


コードをコピー コードは次のとおりです:

/****************** Object-oriented ******************/
/********** 1: Object creation, prototype chain **********/
/* It is important to discuss constructor (class method) to create objects and understand these contents in depth
*/
function MyFunc() { }; //Define an empty function
var anObj = new MyFunc(); //Use the new operator and use the MyFun function to create an object
//Equivalent to:
function MyFunc() { };
var anObj = {}; //Create an object
anObj.__proto__ = MyFunc.prototype;
MyFunc.call(anObj) ; //Call the MyFunc function using the anObj object as this pointer
/*
The process of creating an object in the form of var anObject = new aFunction() can actually be divided into three steps:
Step 1: Create a New object (anObject);
Step 2: Set the object’s built-in prototype object (__proto__) to the prototype object referenced by the constructor prototype;
Step 3: Call the constructor with the object as this parameter , complete initialization work such as member setting.
After the object is created, any access and operation on the object are only related to the object itself and the string of objects on the prototype chain.
It has nothing to do with the constructor.
In other words, the constructor only plays the role of introducing the prototype object and initializing the object when creating an object.
Prototype chain: (Reference: http://hi.baidu.com/fegro/blog/item/41ec7ca70cdb98e59152eed0.html)
Each object (the object here should only refer to the object enclosed in curly brackets, not Including function, array. To be verified? )
will initialize an attribute inside it, which is __proto__. When we access the attribute of an object,
If this attribute does not exist inside the object, then it will Find this attribute in __proto__,
This __proto__ will have its own __proto__, so we keep looking for it, which is what we usually call the concept of prototype chain.
*/
/* After understanding the principle of object creation, you can try to analyze the results of the two examples below*/
var yx01 = new function() {return "Circle Center"};
alert (yx01); // [object Object]
var yx02 = new function() {return new String("center of circle")};
alert(yx02); // "center of circle"
/* Explanation :
"Circle Center" is the basic string type, and new String("Circle Center") creates a string object.
As long as the constructor after the new expression returns a reference object (array, object, function, etc.), it will overwrite the object created by new.
If it returns a primitive type (when there is no return, it actually returns the primitive type undefined ),
then return the object created by new.
Reference: http://www.planabc.net/2008/02/20/javascript_new_function/
*/
/********** 2: Data type detection **********/
/* What you may think of when judging the data type Methods:
constructor, typeof, instanceof, Object.prototype.toString.call()
*/
/***** 1. Through constructor attribute *****/
var myvar= new Array("a"," b","c","d");
function A(){}
myvar.constructor = A;
var c = myvar.constructor;
alert(c); // function A(){}
//It can be seen that the method of obtaining the type through the constructor attribute is easily modified and should not be used to determine the type.
/***** 2. Through typeof *****/
/*
typeof is an operator, not a function.
The practical application of typeof is to detect whether an object has been defined or assigned a value.
For example, if(typeof a!="undefined"){}, do not use if(a) because if a does not exist (undeclared), an error will occur.
When typeof detects the object type, it can generally only return the following results:
number, boolean, string, function, object, undefined.
Using typeof for Array, Null, custom objects, etc. will always return object.
This is the limitation of typeof.
*/
var num = new Number(1);
var arr = [1,2,3];
alert(typeof num); //object instead of number
alert (typeof arr); //object instead of Array
alert(typeof null); // object
/***** 3. Through instanceof *****/
/* Use instanceof operator to determine whether the object is an object Instance of class.
If obj instanceof Class returns true, then the prototype of Class is the same object as a prototype on the obj prototype chain,
that is, obj is either created by Class or a subclass of Class.
*/
function t(){};
t.prototype = Array.prototype;
//t.prototype = [];
var x = new t();
alert(x instanceof t);//pop true
alert(x instanceof Array);//pop true
alert(x instanceof Object);//pop true
/*
by It can be seen that judging the data type through instanceof is not reliable either.
Because the prototype chain of an object (here x) can be very long, the type of each prototype can be different.
In addition, it is also easy to make errors within an iframe:
That is, there is a page that defines an array a, and the page has an IFrame nested in it. If top.a instanceof Array is passed in the Iframe, it will return false.
This description indicates that the objects in the parent page and the embedded iframe are different and cannot be mixed together.
top.ainstanceoftop.Array に変更すると true が返されます
*/
/***** 4. Object.prototype.toString.call() を通じて *****/
/*
Object.prototype.toString.call() 関数 Itは:
1. オブジェクトのクラス名 (オブジェクト型) を取得します。
2. 次に[オブジェクト、取得したクラス名]を結合して返します。
配列、日付、関数、その他の型のオブジェクトを決定するために使用できます。
*/
var num = new Number(1);
var arr = [1,2,3]; 🎜>alert(Object.prototype.toString.call(num)); // [オブジェクト番号]
alert(Object.prototype.toString.call(arr)) // [オブジェクト配列]
//拡張例: (apply は call と同等)
window.utils = {
toString: Object.prototype.toString,
isObject: function (obj) {
return this.toString.apply(obj) ) = == '[オブジェクト オブジェクト]';
},
isFunction: function (obj) {
return this.toString.apply(obj) === '[オブジェクト関数]'; >} ,
isArray: function (obj) {
return this.toString.apply(obj) === '[オブジェクト配列]';
}
}
function A() { }
window.utils.isFunction(A); //true
window.utils.isObject(new A()); //true
window.utils.isArray([]); true
/*
jQuery などのフレームワークではこのメソッドを使用してオブジェクトの種類を判定するため、権威のある判定方法として利用できます。
ただし、Object.prototype.toString メソッドをオーバーライドすると、それを使用してデータ型を決定するときにエラーが発生する可能性があります。
そのため、通常は Object.prototype.toString メソッドをオーバーライドしないでください。
*/
/********** 3: 相続 **********/
/*
クロージャと同様に、JS の継承は、JS を詳しく学びたいほぼすべての友人が議論しなければならない問題です。すべての関連情報が入手可能です。
JS 継承コードには多くのバージョンがありますが、原則は同じで、コアはプロトタイプ オブジェクトを使用します。
他のオブジェクト指向言語のスタイルに似せるために、そのほとんどは「クラス」スタイルのシミュレーションを使用します。
継承の詳細な原​​則については詳しく説明しません。インターネット上には多くの情報があります。
これは例です: Jquery 作者 John Resig によって書かれた継承。
(詳細なコメントはブログからのものです。誰が作成したかわからないため、ここに非公開で再投稿します)
*/
(function () {
// 初期化変数が使用されます)現在のクラスの作成フェーズにあるかどうかをマークします。
// - クラスの作成フェーズではプロトタイプ メソッド init を呼び出すことはできません
// - この問題については、第 3 回で詳しく説明しています。このシリーズの記事
// fnTest は正規表現です。取り得る値は (/b_superb/ または /.*/) です。
// - /xyz/.test(function() のテスト) { xyz; }) は、ブラウザーがテスト パラメーターが関数である場合をサポートしていますか?
// - ただし、IE7.0、Chrome2.0、および FF3.5 をテストしたところ、このテストはすべて true を返しました。
// - したがって、fnTest に値を割り当てることはほとんどの場合正しいです: fnTest = /b_superb/;
varInitializing = false, fnTest = /xyz/.test(function () { xyz; }) ? /b_superb/ : /.*/ ;
// 基本クラスのコンストラクター
// これは window なので、このコード全体が外部の世界へのウィンドウを開きます - window.Class
this。 Class = function () { } ;
// 継承されたメソッド定義
Class.extend = function (prop) {
// ここは非常にわかりにくいので、このシリーズの 2 番目の記事で述べたことを思い出してください。
// - これが具体的に何を指すのかは、定義時には決定できませんが、この関数の呼び出し方法によって異なります。
// - extend はコンストラクターとしてではなくメソッドとして呼び出す必要があることはすでにわかっています
// - したがって、ここでは this はオブジェクトではなく関数 (つまり、クラス) を指しています。その場合、this.prototype は親クラスのプロトタイプ オブジェクトです。
// - 注: _super は親クラスのプロトタイプ オブジェクトを指します。親クラスの場合、次のコードでこの変数に何度も遭遇します
var _super = this.prototype;
// サブクラスのプロトタイプを親クラスのインスタンス オブジェクトにポイントすることで継承が完了します
// - 注: this は基本クラスのコンストラクター (つまり、クラス)
initializing = true;
varprototype = new this();
initializing = false;コードは作者によって最適化されているため、非常に単刀直入に読めます。後で詳しく説明します。
for (var name in prop) {
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "関数" && fnTest.test(prop[name]) ?
(function (name, fn) {
return function () {
var tmp = this._super; // ここは必要に応じて、91 行目のコメント コードで説明できます。
this._super = _super[名前];
var ret = fn.apply(this, argument);
return
; })(name, prop[name]):
prop[name];
}
// この場所から、Resig は変装が非常に上手であることがわかります
// - を使用します同じ名前のローカル変数を使用してグローバル変数をオーバーライドすると、非常に混乱します
// - 発音しにくい場合は、関数 Class() の代わりに関数 F() などの別の名前を使用できます
// - 注: ここでの Class は、最外層で定義された基本クラスのコンストラクターではありません
// ここでの Class は、上記の window.Class 関数とは異なります。ここでは、window.Class
function 内の関数ローカル変数を示します。 Class() {
// クラスをインスタンス化するときに、プロトタイプ メソッド init
if (!initializing && this.init)
this.init.apply(this, argument); を呼び出します。 🎜>// サブクラスのプロトタイプは、親クラスのインスタンスを指します (継承を完了するためのキー)
Class.prototype =prototype; // クラスは、初期ウィンドウではなく、上のクラスを参照します。Class
// コンストラクターのポインティングエラーを修正します
// Class.prototype.constructor = Class; を使用することで修正できますか? ? ?
Class.constructor = Class;
// サブクラスは、現在実行中の関数を指す extend メソッドを自動的に取得します。
Class.extend = argument.callee;
> };
})();
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。