【javascript関数基礎知識】

16521 ワード

関数は実際にオブジェクトであり、各関数はFunctionタイプの実例であり、他の参照タイプと同様に属性と方法を有する.関数はオブジェクトですので、関数名は実際に関数オブジェクトを指すポインタでもあり、関数とは結合されません.
【概念ラベル】
関数申明は、関数表現の匿名関数を値の関数として、argmentsオブジェクトのcaleeの属性再帰関数のcall()メソッド関数のbind()メソッドのクローズド関数として再ロードします.
【関数を定義する方法】
1.関数を定義する3つの方法:関数の説明と関数の表現.
関数で説明する文法は以下の通りです.
function functionName(arg0,arg1,agr2){

    //   

}
関数の説明には重要な特徴があります.すなわち、コードの実行前に関数の説明を読みます.これは、関数の説明文を呼び出し文の後に置くことができることを意味します.
sayHi();

function sayHi(){

    alert('hi');

}
関数式の文法は以下の通りです.
var myFunction = function(arg0,arg1,arg2){

    //   

};
関数申明{}の末尾にセミコロンを付ける必要はなく、関数式を使う場合 {}末尾には、他の変数を説明するように、セミコロンを追加する必要があります.
このような場合は、従来の変数割当文のように見えます.すなわち関数を作成し、変数myFunctionに値を与えます.この場合に作成された関数は匿名関数と呼ばれています.関数式は他の表式と同様に、使用前に値を先に与えなければなりません.以下のコードはエラーを引き起こします.
sayHi();   //

var  sayHi = function(){

    alert('hi');

}
Functionコンストラクターを使って、文法は以下の通りです.
function sum = new Function ('num1','num2','return num1 + num2');
【値の関数として】
関数名自体は変数ですので、関数も値として使用できます.つまり、伝達パラメータのように一つの関数を別の関数に渡すだけでなく、一つの関数を別の関数の結果として返すことができます.たとえば、オブジェクト配列があると仮定して、行列をオブジェクト属性に従って並べ替えます.配列sort()メソッドに渡す比較関数は、2つのパラメータ、すなわち比較する値を受信します.しかし、どの属性で並べ替えられているかを指定する方法が必要です.このケースを実現します.この問題を解決するには、関数を定義して属性名を受信し、この属性に基づいて比較関数を作成します.コードは以下の通りです.
function createComparisonFunction(propertyName){

    return function(obj1,obj2){

        var value1 = obj1[propertyName];  

        var value2 = obj2[propertyName];



        if(value1 < value2){

            return -1;

        }

        if(value1 > value2){

            return 1;

        }

        else{

            return 0;

        }

    }

}
ここでは、行コードに注意してください.var value 1=obj 1[propertyName]  このステートメントは、括弧表現法を使用して属性の値を取得します.ステートメントの実行結果は、Obj 1.propertyNameと同じです.四角い括弧文法を使用する場合、訪問する属性は文字列で括弧に入れるべきです.たとえば:
person['name'];

person.name;
次に、オブジェクト配列を作成し、指定された方法でこのオブジェクト配列を並べ替えます.コードは以下の通りです.
var data = [{name : 'Zachary',age : 19},{name : 'Nicolas',age : 29}];

data.sort(createComparisonFunction('name'));

console.log(data[0].name);   // Nicolas

data.sort(createComparisonFunction('age'));

console.log(data[0].name);   // Zachary
ここで私たちは一つのことに関わります. sort()メソッドは、配列の要素を並べ替えるために使用されます.例えば、以下のコードは、小さいときから大きい順に配列された配列要素を実現する.
function sortNumber(a, b)

{

    var obj = a - b;

    return obj;

}



var arr = new Array(6)

arr[0] = "10";

arr[1] = "5";

arr[2] = "40";

arr[3] = "25";

arr[4] = "1000";

arr[5] = "1";



document.write(arr + "<br />");

document.write(arr.sort(sortNumber));
コードの出力結果は以下の通りです.
10,5,40,25,1000,11,5,10,25,40,1000
【関数の内部属性】
関数の内部には2つの特殊なオブジェクトがあります.argmentsとthisです.
まず紹介します アーグメンントオブジェクト.アーgmentsは、クラスの配列のオブジェクトであり、Arayの例ではなく、入力関数のすべてのパラメータを含み、その各要素は、括弧文法によってアクセスできます.使用 argmentsのlength属性は、以下のコードのようないくつかのパラメータが入ってくるかを決定することができる.
function showArguments(){

    console.log(arguments.length,arguments[0],arguments[1],arguments[1]);

}

showArguments('arg1','arg2','arg3');
コードの出力結果は、3「arg 1」「arg 2」「arg 2」です. 
argmentsオブジェクトにはcaleeという属性があります.この属性はポインタで、持つことを指します. アーグメンントオブジェクトの関数.以下のコードは、古典的な再帰的階乗関数を実現します.
function factorial(num){

    if(num <= 1){

        return 1;

    }

    else{

        return num * factorial(num - 1);

    }

}
ここでは再帰的アルゴリズムを用いて再帰関数の概念を熟知する必要があり、再帰関数は名前で自身を呼び出す関数で構成される.この関数の実行と関数名 funcFactorialはしっかりと結合しています.このような緊密な結合現象を解消するために、argments.caleeを使用できます.コードは以下の通りです.
function factorial(num){

    if(num < 1){

        return 1;

    }

    else{

        return num * arguments.callee(num - 1);

    }

}
このようにすれば、参照関数にどんな名前を使っても、正常に再帰的に呼び出されることが保証されます.例えば以下のコード:
function factorial(num){

    if(num < 1){

        return 1;

    }

    else{

        return num * arguments.callee(num - 1);  //    arguments.callee

    }

}



var newFactorial = factorial;

factorial = function(){

    return 0;

}

var result1 = factorial(5);  //  0

var result2 = newFactorial(5);  //120

console.log(result1,result2);
私たちがargments.caleeを使用しないと、例えば以下のコードはnewFactorial関数を正しく呼び出すことができません.
function factorial(num){

    if(num < 1){

        return 1;

    }

    else{

        return num * factorial(num - 1);  //     arguments.callee

    }

}



var newFactorial = factorial;

factorial = function(){

    return 0;

}

var result1 = factorial(5);  // 0

var result2 = newFactorial(5);   // 0

console.log(result1,result2);
これはどういう理由ですか?自分で考えてみましたが、結論は次のようになりました. var newFactorial=factoralは、関数を呼び出すのではなく、括弧を持たない関数名を使用します.したがって、newFactorialが訪問したのはfactorialの関数ポインタです.再帰関数を次のように変えたのと同じです.
function newFactorial(num){

    if(num < 1){

        return 1;

    }

    else{

        return num * factorial(num - 1);

    }

}
この時、else文はfactoralを実行していますが、明らかに自身の関数を呼び出しられないので、コードを下記のように変更します.
function factorial(num){

    if(num < 1){

        return 1;

    }

    else{

        return num * newFactorial(num - 1);  //      

    }

}



var newFactorial = factorial;

factorial = function(){

    return 0;

}

var result1 = factorial(5);  // 0

var result2 = newFactorial(5);  // 120

console.log(result1,result2);
これで私達は私達の欲しい結果を出力することができます.
次に、thisの対象を紹介します.thisは、関数が実行する環境オブジェクトを参照して、次の例を参照してください.
window.color = 'red';

var o = {color : 'blue'};

function sayColor(){

    console.log(this.color);

}

sayColor();   // red

o.sayColor = sayColor;

o.sayColor();   // blue
上のこの関数sayColor()はグローバルスコープで定義されていて、thisオブジェクトを参照しています.関数を呼び出す前にthisの値が確定しないため、thisはコード実行中に異なるオブジェクトを参照することがあります.グローバルスコープで呼び出し  sayColorの場合、thisは全体の対象windowを引用しますので、this.co lorに対する求値はwindow.co lorに対する求値に変換されます.私たちはこの関数をオブジェクトに割り当ててoを呼び出します. sayColor()の場合、this.co lorは値を求めるとo.co lorの値を求めるに変換されます.
【関数のコール方法】
 call()メソッドが強いところは、関数のスコープを拡張することができます.次のコードを確認します.
window.color = 'red';

var o = {color : 'blue'};

function sayColor(){

    console.log(this.color);

}

sayColor();   // red

sayColor.call(this);   // red

sayColor. call(window);   // red

sayColor.call(o);   //blue
コードの最後の行を観察して実行します. sayColor.call(o)の時、関数の体内のthisの対象はoを指して、このように使わなくてもいいです. o.sayColor=sayColor;o.sayColor() この文です
【関数のbind()方法】
この方法はオブジェクトの例を作成し、そのthisの値はbind()関数の値に結び付けられます.下記のコードをチェックします.
window.color = 'red';

var o = {color : 'blue'};

function sayColor(){

    console.log(this.color);

}

var newSayColor = sayColor.bind(o);

newSayColor();    //blue
【閉包】
クローズドとは、別の関数のスコープにアクセスする権限を持つ変数の関数です.閉じたパケットを作成する一般的な方法は、関数の内部に別の関数を作成することです.
【重量がない】
関数の再ロード:同じ範囲でいくつかの機能が似ている同名の関数を宣言しますが、これらの同名の関数の形式パラメータ(パラメータの数、タイプまたは順序を指します)は異なる必要があります.つまり同じ演算子で異なる演算機能を完成します.これがリロード関数です.機能が類似していて、処理されたデータの種類が異なる問題を達成するために、リロード関数がよく用いられる.
関数名をポインタとして想像すると、ECMAScriptに関数がない理由を理解するのに役立ちます.下記のコードをご覧ください.
function addNumber(str){

    return str + '100';

}

function addNumber(num){

    return num + 200;

}

window.onload = function(){

    var addContent = addNumber('100');

    console.log(addContent);

}
もし関数の再負荷が有効になれば、上記コードの出力内容は100100で、正しい出力結果は100200です.下記のコードを再検討します.
function addNumber(str1,str2){

    return str1 + str2 + '102';

}

function addNumber(num){

    return num + 200;

}

window.onload = function(){

    var addNum = addNumber('100','101');

    console.log(addNum);

}
出力結果は:100200 
関数はプログラミングの重要な部分で、練習を強化して、多く勉強します.自分を励ます言葉をここに貼ってください.怖くないはずがないです.勉強しないのが怖いです.