JavaScript-関数基礎学習

39855 ワード

JavaScript-関数基礎学習
どのプログラミング言語にも関数があります.関数はステートメントのセットを封入して、特定の機能を完成させます.本編ではJavaScriptの関数を勉強します.
関数の定義には多くの方法があります.関数の表現、関数の表現、矢印の関数、new Function、ジェネレータの関数など、本記事では最も基本的によく使われているものを紹介します.
  • 関数宣言
  • 関数パラメータ
  • アーグメンント
  • 拡張式
  • パラメータのデフォルト値
  • 関数式
  • 矢印関数
  • 矢印関数は、this
  • がありません.
  • 矢印関数は、argments
  • がありません.
    関数の説明
    JavaScript関数はfunctionキーワードで説明します.
    function functionName(parameter){
        //   
    }
    
    次のように関数を宣言します.関数名はhelloです.
    function hello(){
        console.log('world');
    }
    hello();
    
    hello()によってこの関数を呼び出すことができ、本例は、コンソール出力world関数宣言後に、複数回起動することができる.
    関数のパラメータ
    関数にパラメータを追加することができます.以下のように、add関数を宣言します.この関数は2つの整数パラメータを受信し、2つの合計を返します.
    function add(num1, num2){
        return num1 + num2;
    }
    add(1, 2);
    
    パラメータが単純なタイプの場合、Number,Booleanなど、関数に伝達されるのは変数のコピー、すなわちパラメータの値を関数内で修正しても元の変数の値は変わりません.
    function add(num1, num2){
        num1 = 2;
        return num1 + num2;//4
    }
    let num1 = 1;
    console.log(num1);//     ,num1 1
    add(num1,2);
    console.log(num1);//     ,num1   1
    
    関数内でnum1の値が修正されたが、外部変数num1は変更されていないことがわかる.
    伝達されるパラメータが参照の種類である場合は、オブジェクトのように異なる場合があります.
    function add(obj) {
        obj.num1 = 2;
        return obj.num1 + obj.num2;
    }
    let obj = { num1: 1, num2: 2 };
    console.log(obj.num1); //     ,obj.num1 1
    add(obj);
    console.log(obj.num1); //     ,obj.num1 2
    
    参照タイプが参照伝達によるものであるため、関数内でパラメータobjのnum1属性の値が修正され、外部変数objオブジェクトの属性num1の値が実際に変更されていることが分かる.
    function add(obj) {
        obj = { num1:2, num2:3};
        return obj.num1 + obj.num2;
    }
    let obj = { num1: 1, num2: 2 };
    console.log(obj.num1); //     ,obj.num1 1
    add(obj);
    console.log(obj.num1); //     ,obj.num1   1
    
    ここで、関数内部で直接にパラメータobjに値を与え、結果として外部オブジェクトobjの値に影響を与えていないことが分かります.このオブジェクトの指向を変えることができないので、このオブジェクトの属性を変更するしかありません.再割当は許可されません.
    多くの人がここで参照型の変数について議論していますが、パラメータの伝達時は値によるものなのか、それとも引用によるものなのかについて議論しています.ここでは葛藤する必要はないと思います.引用伝達によるものだと思いますが、関数内部で に再割り当てが許可されていないことを覚えてください.他の観点があれば、私のを無視してください.
    隠しオブジェクト
    例:
    function add(num1, num2){
        console.log(arguments.length);//2
        console.log(arguments[0]);//1
        console.log(arguments[1]);//2
    }
    add(1, 2);
    
    argments.lengthでパラメータの個数を取得できます.argmentsオブジェクトは配列に似ていますが、実際には配列ではありません.
    実際には、関数を宣言する際に関数パラメータを加えず、アーグメンントオブジェクトにもアクセスできます.
    function add(){
        console.log(arguments.length);//2
        console.log(arguments[0]);//1
        console.log(arguments[1]);//2
    }
    add(1, 2);
    
    もう一つのポイントは、JavaScriptには関数の重載がなく、パラメータの個数が違ってもだめです.
    function add(num1){
        return 10 + num1;
    }
    
    function add(num1, othernumber){
        return 20 + num1;
    }
    
    add(10);
    
    この例は何を出力しますか?答えは30で、後に作成された関数addが前のaddを覆っているからです.
    argmentsを利用してパラメータの個数とタイプを判断できます.
    function add(){
        if(arguments.length == 1){
            return arguments[0];
        } else (arguments.length == 2){
            return arguments[0] + arguments[1];
        }
    }
    console.log(add(1));//1
    console.log(add(1, 2));//3
    
    拡張式ES6 (Rest Expression)を導入し、3つの点...によって表現され、拡張式受信関数パラメータのタイプは1つの配列である.
    function add(...nums) {
        let sum = 0;
        for (let num of nums) {
            sum += num;
        }
        return sum;
    }
    console.log(add(1)); //1
    console.log(add(1, 2)); //3
    console.log(add(1, 2, 3)); //6
    
    ここのnumsは本物の配列であり、拡張式は通常のパラメータと一緒に使用できますが、一番後ろに置かなければなりません.
    function add(firstnum, ...restnums) {
        let sum = 0;
        for (let num of restnums) {
            sum += num;
        }
        return firstnum + sum;
    }
    console.log(add(1)); //1,restnums []
    console.log(add(1, 2)); //3,restnums [2]
    console.log(add(1, 2, 3)); //6,restnums [2,3]
    
    があったら、argumentsを使用する必要はありません.argumentsは配列ではないので、配列方法は使えません.たとえばarguments.forEach(...)を使用することはできません.argumentsはすべてのパラメータを含んでいます. は部分パラメータだけを収集することができます. を使ってargumentsより優れています.これもjavascript-style-style-guideの提案です.
    パラメータのデフォルト値
    関数のパラメータにデフォルト値を指定できます.関数を呼び出したとき、デフォルトのパラメータに値を伝えないとパラメータの値はデフォルトです.デフォルトのパラメータに値を伝えると、パラメータの値は実際に伝えられた値ですが、デフォルトのパラメータはパラメータの一番後ろに表示されます.
    function add(num1, num2 = 1){
        return num1 + num2;
    }
    add(1);//2,        num2  ,num2    1
    add(1, 2);//3,       num2  ,num2     2
    
    関数式
    前に述べた関数の定義方法、関数宣言:
    function functionName(parameter){
        //   
    }
    functionName();//  
    
    実際のjavascriptには、関数を変数に割り当てることもできます.このような形式は、関数式と呼ばれます.
    let functionName = function(parameter){
        //   
    }
    functionName();//  
    
    このような書き方は、匿名関数を変数に指定するものであり、呼び出しもfunctionName()によって行われる.
    注意:関数式は与えられた値の後にのみ呼び出されますが、普通の関数宣言は作成の前後に呼び出されます.
    foo();//     ,  foo,  
    function foo(){
        console.log('bar');
    }
    foo();//     ,  foo,  
    
    foo();//     ,  foo,  ReferenceError
    let foo = function(){
        console.log('bar');
    }
    foo();//     ,  foo,  
    
    関数の値を任意の変数に割り当てることもできます.
    function functionName(parameter){
        //   
    }
    let anotherfunctionName = functionName;
    
    その後、anotherfunctionName()を介して呼び出すことができ、functionName()の呼び出しと同じである.
    ES 6矢印関数ES6は矢印関数を導入しています.書き方は従来の関数宣言より簡便で、例えば上記のadd関数は矢印関数に書き換えられます.
    let add = (num1, num2) => num1 + num2;
    
    console.log(add(1, 2)); //3
    
    矢印の左側にかっこで囲まれているのは、カンマで区切られたパラメータで、矢印の右側に式があります.複数の語句がある場合は、大かっこで囲む必要があります.
    let add = (num1, num2) => {
        let sum = num1 + num2;
        return sum;
    };
    console.log(add(1, 2)); //3
    
    矢印の右側に1つの表現しかない場合は、大括弧を省略してもいいです.returnを書く必要はなく、デフォルトを書くとnum1 + num2に戻ります.
    let add = (num1, num2) => num1 + num2;
    
    ただし、大きな括弧で包んだら、returnと書かなければなりません.そうでなければ、戻り値はありません.以下のように、undefinedと出力されます.
    let add = (num1, num2) => {
        num1 + num2;
    }
    console.log(add(1, 2));//undefined
    
    javascript-style-guideでは、矢印関数の右側に1つの文があるときに、大きな括弧を書かないで、暗黙的に返さないと、大括弧で包んでreturnを使って戻ります.
    矢印関数にはthisがありません.
    矢印関数にthisがないなら、矢印関数のthisはどこにありますか?
    まず、一般関数のthisを見てみます.thisは呼び出しの対象と関係があり、直接関数を呼び出します.thisはundefinedです.
    function add(){
        console.log(this);//undefined
    }
    add();
    
    オブジェクトで関数を呼び出す:
    let myObj = {
        num1:1,
        num2:2,
        add() {
            return this.num1 + this.num2;
        }
    }
    console.log(myObj.add());//3
    
    このときaddの関数のthisは、その使用者myObjであるので、出力3
    矢印関数のthisを見てください.
    let myObj = {
        num1: 1,
        num2: 2,
        add() {
            let sum = () => this.num1 + this.num2;
            return sum();
        }
    }
    console.log(myObj.add()); //3
    
    矢印関数にthisがないので、そのthisは実際には上の階のthisであり、この例の矢印関数のthisは実際にはmyObjである.
    普通の関数であれば、
    let myObj = {
        num1: 1,
        num2: 2,
        add() {
            let sum = function() {
                return this.num1 + this.num2;
            }
            return sum();
        }
    }
    console.log(myObj.add()); //NaN
    
    一般的な関数はthisであり、本例ではthisがそのデフォルト値undefinedを取っているので、this.num1およびthis.num2undefinedであり、undefined+undefinedNaNである.
    矢印関数にはargmentsがありません.
    前に述べた関数宣言には、隠しアーグメンントオブジェクトがありますが、矢印関数にはこのオブジェクトがありません.argumentsを使用すると、前のレイヤーから取り出されます.
    function add(num1) {
        let sum = () => {
          arguments[0] + num1;//   arguments  add arguments
        };
        return sum();
    }
    console.log(add(1));//2
    console.log(add(2));//4
    
    締め括りをつける
  • 関数宣言:function name(){}、関数は、任意の変数に値を割り当てることができます:let anothername = name、その後、anothername ()を介して
  • を呼び出すことができます.
  • 関数式:let name = function(){}、関数式の使用は推奨されていません.与えられた値の後にしか起動できないため、関数宣言は向上され、宣言の前後に呼び出すことができます.
  • 関数パラメータ:伝達パラメータが単純なタイプの場合、伝達されるのは変数のコピーであり、パラメータが参照タイプの場合、伝達されるのは変数の参照
  • である.
  • 非表示のオブジェクトargumentsは、argumentsと同様の配列であるが、実際にはオブジェクトであり、argumentsを介して関数パラメータ
  • にアクセスすることができる.
  • 拡張式:拡散式は伝達されたパラメータを受信するために用いられ、データタイプは配列であり、拡張式はargumentsに比べていくつかの利点があるので、 ではなく、arguments
  • を使用したほうがいい.
  • 矢印関数:ヘッドカット関数はES6によって導入され、従来の関数宣言方式よりも簡潔に書かれている.
  • 矢印関数にはthisがありません.矢印関数のthisは、その上の階のthis
  • であることが分かります.
  • 矢印関数にはargumentsがありません.矢印関数のargumentsは、その上の階のarguments
  • であることが分かります.
    参照
    1.MDN-関数:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions 2.値で送るか、それとも引用で伝えるかについて:https://hackernoon.com/grasp-by-value-and-by-reference-in-javascript-7ed75efa1293
    執筆時間:2020-05-31