1. 関数の定義
関数には、JavaScript の基本モジュール単位である一連のステートメントが含まれており、コードの再利用、情報の非表示、呼び出しの結合に使用されます。関数はオブジェクトの動作を指定するために使用されます
2. 関数の 4 つの呼び出しモードとその初期化
最初: メソッド呼び出しモード
次の例は、メソッド呼び出しモードを通じて呼び出された場合、これがメソッドを所有するオブジェクトにバインドされることを証明しています。例:
var person = {
名前: "デフォルト名",
setName : 関数(名前){
This.name = 名前;
}
};
person.setName("張三");
アラート(人名);
2 番目のタイプ: 関数呼び出しモード
次の例は、関数呼び出しモードで呼び出された場合に、これがグローバル オブジェクトにバインドされることを示しています。例:
var test = add(value1, value2);
var name = "デフォルト名";
var person = {
name: "zhangsan", // 個人で定義された名前
GetName : function(){
// このメソッドはテスト関数の this を person の this オブジェクトに変更できます
var that = this; // 解決策
// getName で定義された名前
var name = "lisi";
var test = function(){
//それを通じてオブジェクトに直接アクセスします
// これはグローバル オブジェクト
を指します
// this.name = defaultName
// that.name = zhangsan
alert([この名前, その名前]);
};
test() // 関数呼び出しモード
;
}
}
person.getName();
3 番目のタイプ: コンストラクター呼び出しモード
// Person コンストラクターを定義します。これは new
で呼び出す必要があります。
var 人 = 関数(名前){
This.name = 名前;
}
// メソッドを Person
に追加します
Person.prototype.getName = function(){
this.name を返します;
};
// 人物オブジェクトを構築します
var person = 新しい人("zhangsan");
alert(person.getName()); // getName を呼び出して person オブジェクトの name 属性の値を取得します
4 番目: 通話モードを適用します
<スクリプトタイプ="text/javascript">
//蓄積方法を決定する。 sum(1,2,3,4...)
など
// このメソッドはウィンドウ実行環境にあります。
var displayName = function(){
alert("合計実行環境: " typeof(this));
alert("Name: " this.name) // 現在の実行環境の name 属性を取得します
}
// 人物オブジェクトを決定します
var 人 = {
名前: "zhangsan"
};
DisplayName.apply(人);
3. 申請と呼び出しの違い
// a と b の合計を返す add メソッドを含むオブジェクトを定義します
var 人 = {
'add' : function(a, b){
return a b;
}
};
// a と b の合計を表示します
関数 showInfo(a, b){
alert(this.add(a, b));
}
// apply メソッドを使用して showInfo メソッドの this ポイントを変更します
//showInfo(1, 3); // オブジェクトはセカンダリ オブジェクトをサポートしていません
showInfo.apply(人, [1, 3]);
showInfo.call(人, 1, 3);
// 上記からわかるように、apply と call の違いは、apply は呼び出される関数
のパラメーターとして配列を受け入れることです。
// そして、call は呼び出された関数のすべてのパラメータをカンマ区切り形式で展開します
4. 関数パラメータ (引数)
引数は配列ではありませんが、配列に似ています。引数には、長さプロパティがあるだけでなく、配列のすべてのプロパティとメソッドがあるわけではありません。引数を使用して累積関数を実装します。
関数 sum(){
var total = 0;
for(var i=0; i
合計 = 引数[i];
}
合計を返します;
}
alert("合計: " 合計(1, 3, 2, 4));
5. 関数の戻り値(return)
関数が呼び出される場合、通常は関数の{から}までが実行されます。関数の実行を早期に終了したい場合は、return ステートメントを使用できます。この時点では、return ステートメントに続くすべてのステートメントは実行されません。例:
関数テスト(){
alert("最初");
戻る;
alert("second"); // このステートメントは決して実行されません
}
テスト();
// 関数は常に値を返します。戻り値が使用されない場合は、デフォルトで未定義が返されます。例:
関数テスト(){
アラート("最初");
}
alert(test()); // 出力: 未定義
// new メソッドを使用して関数が呼び出され、戻り値がオブジェクトでない場合は、これ (新しいオブジェクト) を返します。例:
関数テスト(){
alert("最初");
}
var t = 新しいテスト();
alert(typeof t); // 出力: 'オブジェクト'
アラート(t インスタンスオブテスト); // 出力: true
6. 例外
異常とは、プログラムの正常な流れを妨げる異常な事故 (おそらく意図的) です。このようなインシデントが検出された場合は、例外がスローされる必要があります。例:
function add(a, b){ // 加算関数を定義します
// 渡されたパラメータが数値型でない場合、例外メッセージがスローされます
If(typeof a != '数値' || typeof b != '数値'){
スロー {
'name' : "typeError", // 属性はカスタマイズされており、任意の名前を付けることができます
'message': "add メソッドはパラメーターとして数値を使用する必要があります"
};
}
b を返します;
}
(関数(){
//add メソッドによって生成される可能性のある例外をキャッチします
試してください{
add(10, "");
} catch(e){
//try ステートメントには catch ステートメントが 1 つだけあります。複数の例外を処理する場合は、例外の name 属性によって区別されます
// 例外の種類を決定します
If(e.name === "typeError"){
アラート(e.メッセージ);
}
}
})();
7. 型にメソッドを追加します
JavaScript では、基本型にメソッドを追加できます。例: ブール値、文字列、数値
例: メソッド関数を Function に追加し、これにより他のカスタム関数が Function に追加されます (プロトタイプの使用は避けてください)。その後、メソッド関数を使用して add 関数を Function に追加し、最後に add 関数が Function に存在するかどうかをテストします。このメソッドは、func 関数を Function に追加し、それに name を付けます。次に、Function オブジェクト
を返します。
Function.prototype.method = function(name, func){
// 既存のメソッドを上書きしないようにします
If(!this.prototype[名前]){
This.prototype[名前] = func;
}
これを返してください;
};
//Function.method メソッドを通じて加算関数を Function に追加します。関数の名前は「add」です。
Function.method("add", function(a, b){
If(typeof a != '数値' || typeof b != '数値'){
スロー {
'name' : "typeError",
'message' : "add メソッドは数値を渡す必要があります"
};
}
b を返します;
});
// Function の add メソッドを呼び出して、関数が存在するかどうかを確認します
(関数(){
試してください{
alert(Function.add(1, 3)); // 出力: 4
} キャッチ(e){
If(e.name === 'typeError'){
アラート(e.メッセージ);
}
}
})();
//文字列の両端の空白を削除します
String.method("トリム", function(){
return this.replace(/^s |s $/g, '');
});
alert('|' " hello world ".trim() '|' // 出力: '|hello world|'
//数値の丸め関数を追加
Number.method("整数", function(){
// 次のような方法で関数を呼び出すことができます: Math.random() == Math['random']() == Math["random"]()
数学を返します[this
});
alert((-10 / 3).integer()); // 出力: -3
8. 再帰呼び出し (arguments.callee)
再帰呼び出しとは、自分自身を呼び出すことを意味します。呼び出しは、直接呼び出しと間接呼び出しに分けられます。以下に、指定された値のフィボナッチ数列を計算するための再帰呼び出しの使用法を示します。
// i
の階乗を求めます
関数階乗(i){
If(i
1 を返します;
}
Return i*factorial(i-1) // 再帰呼び出し
;
}
alert(factorial(5)); // 5
の階乗を求めます。
// 上記の方法に問題はありますか?以下のように:
var 階乗 = 関数(i){
If(i
1 を返します;
}
Return i*factorial(i-1); // 階乗はまだ呼び出すことができますか?できません
}
var テスト = 階乗
階乗 = null;
アラート(テスト(2));
// 解決策:
var 階乗 = 関数(i){
If(i
1 を返します;
}
Return i*arguments.callee(i-1); // argument.callee は、指定された Function オブジェクトの本体である、実行中の Function オブジェクトを返します。
}
var test = 階乗;
階乗 = null;
アラート(テスト(5));
9. 範囲
コードをコピー コードは次のとおりです:
// プログラムでは、スコープは変数の可視性とライフサイクルを制御します。
var name = "デフォルト" // グローバルスコープ
;
関数 getName(){
var name = "getName" // getName スコープ
;
for(var i=0; i
var inName = "inName";
}
alert(i "," inName); // 2, inName 注: js にはブロックレベルのスコープはなく、if、for、while で宣言された変数はブロック
のスコープに配置されます。
名前を返します;
}
alert(getName()); // getName 注: js には関数スコープがあるため、関数内で定義された変数は
の外部には表示されません。
アラート(名前); // デフォルト
注: 多くの現代言語では、変数の宣言をできるだけ遅らせることが推奨されています。例: java ただし、js ではブロックレベルのスコープがサポートされていないため、これはお勧めできません。使用するすべての変数を関数の先頭で宣言することをお勧めします。
10. 終わり
関数が作成されたときにその関数が環境にアクセスできるコンテキストは、クロージャと呼ばれます。スコープの利点は、内部関数が外部関数のすべての変数 (この関数と引数を除く) にアクセスできることです。
var myObject = {
値: 0、
インクリメント : function(inc){
This.value = typeof inc === 'number' ? inc : 1;
}、
GetValue : function(){
return this.value;
}
};
myObject.increment(10);
アラート(myObject.value);
alert(myObject.getValue());
// 上記はリテラル定数を使用して myObject オブジェクトを定義しています。ただし、値変数には外部オブジェクト
からアクセスできます。
var myObject = function(){
var 値 = 0;
戻り値 {
インクリメント: function(inc){
値 = typeof inc === '数値' ? inc : 1;
}、
getValue: function(){
戻り値;
}
};
}();
myObject.increment(10);
alert(myObject.value); // 外部オブジェクトからアクセスできません
アラート(myObject.getValue()) // 10
// ボディの背景色のグラデーション (黄色から白)
var fade = function(node){
var レベル = 1;
var step = function(){
var hex = level.toString(16);
Node.style.backgroundColor = '#FFFF' hex hex;
If(レベル
レベル = 1;
setTimeout(step, 500) // レベルが 15 未満の場合、内部関数はそれ自体を呼び出します
}
};
setTimeout(step, 1) // 内部関数を呼び出します
;
};
fade(document.body);
// これは本当に悪い例です
Click me... // クリックされると 3
が表示されます
Click me... // クリックされると 3
が表示されます
Click me... // クリックされると 3
が表示されます
var add_the_handlers = 関数(ノード){
var i;
for(i = 0; i
Nodes[i].onclick = function(e){ // 関数構築: i
アラート(i);
};
}
};
var objs = document.getElementsByName("テスト");
add_the_handlers(objs);
//上記の理由は、a タグのイベント関数が変数 i にバインドされており、関数が構築されたときの i の値ではないためです。
// 解決策は次のとおりです:
var add_the_handlers = 関数(ノード){
var i;
for(i = 0; i
ノード[i].onclick = function(i){
return 関数(e){
alter(i); // i 出力は、イベント処理にバインドされた i ではなく、コンストラクターによって渡された i です。
};
}(i);
}
};
var objs = document.getElementsByName("テスト");
add_the_handlers(objs);
11. コールバック
// data はパラメータを表し、call_function はコールバック関数を表します
function sendRequest(data, call_function){
// setTimeout は、クライアントがサーバーからのデータの送信を要求するのにかかる時間をシミュレートします。
// 3 秒後にコールバック関数を呼び出します (コールバック関数を実装するクライアントがあります)
setTimeout(function(){
call_function(data) // コールバック関数を呼び出します
;
}, 3000);
}
//sendRequest 関数をテストします
sendRequest("パラメータ", function(context){
alert("context="コンテキスト);
});
12. モジュール
モジュールは、インターフェイスを提供しますが、状態と実装を非表示にする関数またはオブジェクトです。
一般的な形式: プライベート変数と関数を定義する関数。クロージャを使用してプライベート変数と関数にアクセスできる特権関数を作成し、最終的にこの特権関数を返すか、アクセスできる場所に保存します。
Function.prototype.method = function(name,func){
This.prototype[名前] = func;
これを返してください;
};
String.method("deentityify",function(){
var エンティティ = {
引用: '"',
gt : '>'
};
戻り関数(){
return this.replace(/&([^&;] );/g, function(a, b){ // a と b の値を知る方法、正規表現を理解する方法
var r = エンティティ[b];
return typeof r === "string" ? r : a;
});
};
}());
alert("<">".deentityify()); // テスト: <">
注: モジュール モードは、通常、シングルトン モードと組み合わせて使用されます。JavaScript のシングルトン モードは、オブジェクト リテラルを使用して作成されたオブジェクトであり、オブジェクトの属性値は数値または関数になります。オブジェクトのライフサイクル中は変化しません。変更は発生します。
13. カスケード(連鎖操作)
値を返さない一部のメソッドの場合は、未定義の代わりにこれを返します。その後、カスケード (連鎖) を開始してオブジェクトを操作できます。以下のように:
コードをコピー コードは次のとおりです:
var $ = 関数(id){
var obj = document.getElementById(id);
obj.setColor = function(color){
this.style.color = color;
これを返します;
};
obj.setBgColor = function(color){
this.style.backgroundColor = color;
これを返します。 // このオブジェクトを返します、启アニメーション级联
};
obj.setFontSize = function(size){
this.style.fontSize = サイズ;
これを返します;
};
obj を返します;
};
$("テスト").setColor("赤")
.setFontSize("30px")
.setBgColor("青");
// 変更後の代番号:
(関数(id){
var _$ = 関数(id){
this.element = document.getElementById(id);
};
_$.prototype = {
setColor : function(color){
this.element.style.color = color;
これを返します;
}、
setBgColor : function(color){
this.element.style.backgroundColor = color;
これを返します;
}、
setFontSize : function(size){
this.element.style.fontSize = サイズ;
これを返します;
}
};
// window 原型链中に追加
window.$ = function(id){
新しい _$(id) を返します;
};
})();
$("テスト").setColor("赤")
.setFontSize("30px")
.setBgColor("青");
14、套用
たとえば、次のコードで add() 関数を定義すると、この関数は新しい関数を返し、その新しい関数にパラメータ値を渡すことができます。したがって、追加操作が実行されます。
复制代码代码如下:
// 最初の方法:
var add = function(a){
戻り関数(b){
return a b;
}
};
アラート(add(1)(2)); // 3
// 2 番目の方法: 引数を使用して
を実装します
var add = function(){
var arg = 引数;
戻り関数(){
var sum = 0;
for(var i=0; i
sum = arg[i];
}
for(i=0; i
sum = 引数[i];
}
合計を返します;
}
};
アラート(add(1,2,3)(4,5,6)); // 21
// 3 番目の方法: アプリケーション メソッド (カレー) を介して
を実装する
var add = function(){
var sum = 0;
for(var i=0; i
sum = 引数[i];
}
合計を返します;
};
//関数のプロトタイプチェーンにメソッドを追加
Function.prototype.method = function(name, func){
This.prototype[名前] = func;
これを返してください;
};
//メソッドを適用
Function.method('カレー', function(){
// 配列 Array のスライス メソッドを通じて、引数には concat メソッドも含まれます
var スライス = Array.prototype.slice,
args = slide.apply(arguments), that = this;
戻り関数(){
return that.apply(null, args.concat(slice.apply(arguments)));
};
});
アラート(add.curry(1,2)(3,4)); // 10
15. 記憶
関数はオブジェクトを使用して以前の操作の結果を記憶することができるため、不必要な操作を回避できます。この最適化は記憶と呼ばれます。
var fibonacci = function(){
var mome = [0,1] // 計算されたデータを保存します
;
var fib = function(n){
var result = mome[n];
// 計算されたデータがない場合は、直接計算します。次に、計算結果をキャッシュします
If(結果の種類 !== '数値'){
結果 = fib(n-1) fib(n-2);
mome[n] = 結果;
}
結果を返します;
};
fib を返します;
}();
for(var i=0; i
document.writeln("// " i ": " fibonacci(i) "
");
}
//==========================
//メモリを使用して関数を作成します
//==========================
var memoizer = function(メモ、基本){
var シェル = function(n){
var result = memo[n];
If(結果の種類 !== "数値"){
結果 = 基本(シェル, n);
memo[n] = 結果;
}
結果を返します;
};
シェルを返します;
};
//メモリ関数 memoizer を通じてフィボナッチ数列を完成させます
var fibonacci = memoizer([0,1], function(shell, n){
シェル(n-1) シェル(n-2)を返します;
});
//メモリ関数メモライザーによる完全階乗
var fastial = memoizer([1,1], function(shell, n){
n * シェル(n-1);
を返します。
});
for(var i=0; i<=15; i ){
document.writeln("// " i ": " fastial(i) "
");
}
理解できましたか? 非常に実践的な内容です。不足している点があれば、専門家に指導を求めてください。一緒に進歩していきましょう。