JS関数

11205 ワード

1、関数宣言と関数表現にはどんな違いがありますか?
  • 関数宣言は関数の初期化と見なすことができます.関数を参照して関数体の表現式を作成します.私たちが確立したら、行関数の表現式を実行できます.やり方は以下の通りです.
  • 関数式は、実際には匿名の関数宣言を作成し、var foo=function()などの変数に値を与えます.
  • 関数宣言を使用すると、JAvascriptの変数名アップグレード機構によって定義されたfoo関数名が影響され、関数式によって作成された関数は、もちろん、最も直接的な特徴は、関数名が省略されています.
  • 他にもいくつかの関数のステートメントの書き方があります.例えば、自己実行関数は、主に新しいスコープを作成するために使われます.このスコープ内で宣言された変数は他のスコープ内の変数と衝突したり、混同したりしません.ほとんどは匿名関数で存在します.構造、工場、混合など
    2、変数の宣言の前に何がありますか?関数の宣言前とは何ですか?
  • 変数のリフティング:変数が定義されている場合、コード実行前に変数を初期化(現在のスコープの上部にアップグレード)してからステートメントを実行します.
  • console.log(a)  //undefined
    var a=1
    console.log(a)  //1
    
  • 関数アップグレード:関数宣言の場合、コード実行前にまず関数を生成し、ステートメント
  • を実行します.
    fn('hello')  //"hello"
    function fn(str){
      console.log(str)
    }
    
    3、アーグメンントとは何ですか?
  • 関数宣言または関数表現では、function fn(v1,v2){...}のように、v 1、v 2は関数のモダリティであり、実際に呼び出したときに入ってきたパラメータは、fn(3,4,5)のようなargmentsに格納されます.
  • アーgmentsはクラスの配列オブジェクトであり、各関数にはargmentオブジェクトが存在し、argmentは本物の配列ではないので、length属性以外の属性は持たない.このオブジェクトはこの関数に入ってくるすべてのパラメータリストを維持する.argmentsは、次の文で配列オブジェクト
  • に変換されます.
    var args=Array.prototype.slice.call(arguments)
    
    4、関数の「積載」はどうやって実現しますか?
  • リロードは、オブジェクト言語に向けて多状態を実現する多くの手段の一つであり、静的言語で関数を決定する手段は、方法によって署名される関数名+パラメータリスト、すなわち同じ名前の関数パラメータの個数が異なるか、または順序が異なるかは、関数リロードと呼ばれる.
  • は、JavaScriptにおいて関数の重み付けの概念がなく、関数は名前によって一意性を決定し、パラメータの違いは同じ関数としても認識され、後ろのカバーの前にあるが、関数のピンで異なるパラメータ呼び出しに対して対応する論理を実行することができる.
  • function printPeopleInfo (name, age, sex){
        if(name){
          console.log(name);
        }
        if(age){
          console.log(age);
        }
        if(sex){
          console.log(sex);
        }
      }
      printPeopleInfo('Byron', 26);
      printPeopleInfo('Byron', 26, 'male');
    
    5、直ちに関数式を実行するとは何ですか?何の効果がありますか
    関数付き宣言と関数式の2つの方法が一般的に定義されていることを知っています.arguments[0]:3,arguments[1]:4,arguments[2]:5 function fnName () {…};   // の違いは:
  • Javascriptエンジンは、Javascriptコードを解析する際に、「関数宣言アップ」(Function declaration Hoisting)が現在実行されている環境上の関数宣言を行いますが、関数式はJavascirtpエンジンが実行されるまでは、上から下の行に関数式を解析する必要があります.
  • 関数式の後には、括弧を入れて直ちに関数を呼び出すことができます.関数宣言はできません.fnName()としてのみ呼び出されます.
  • したがって、関数の後ろに括弧を入れるとすぐに呼び出すことができます.この関数は関数式でなければなりません.関数宣言ではありません.
    functionの前に()、!、+、-、=などの演算子は、関数宣言を関数式に変換し、Javascriptエンジン識別関数表現と関数宣言の曖昧性を削除しました.javascriptエンジンに対しては、関数宣言ではなく、後に括弧を入れて、すぐに関数コードを実行することができます.
    (function(){
      console.log(123)
    })()         //  123
    
    (function(){
      console.log(123)
    }())         //  123
    
    !function(){
      console.log(123)
    }()         //  123
    
    +function(){
      console.log(123)
    }()         //  123
    
    -function(){
      console.log(123)
    }()         //  123
    
    var a=function(){
      console.log(123)
    }()         //  123
    
    括弧を入れるのは一番安全な方法です.などの演算子は、関数の戻り値と演算しますが、必要でないトラブルを引き起こす場合があります.
    このようにして何の役割がありますか?大域または局部的な作用領域に変数が宣言されています.他の人が誤って同じ名前の変数を使って上書きしてしまうかもしれません.javascript関数の作用するドメインチェーンの特性によって、この技術を使ってプライベートスコープを模倣できます.匿名関数を「容器」として使用して、「容器」内部は外部の変数にアクセスできます.外部環境は「容器」内部の変数にアクセスできませんので、内部定義の変数は外部の変数と衝突しません.
    6、nを求める再帰的に実現する
    nを利用しますn(n-1)(n-1)等しい(n-1)((n-1)-1)!括弧内の値が1になるまで、他の0!1に等しい
    function fac(n){
      if( n===1 || n===0 ){return 1}
      return (n*fac(n-1))
    }
    console.log(fac(1))     //  1
    console.log(fac(2))     //  2
    console.log(fac(3))     //  6
    console.log(fac(4))     //  24
    console.log(fac(5))     //  120
    
    三元演算子も使えますか?文章を書く:
    function fac(n){
      return n===0 || n===1 ? 1 : n*fac(n-1)
    }
    console.log(fac(5))     //  120
    
    またサイクルを利用しても良いです.
    function fac(n){
      var i =1
      if( n===1 || n===0 ){console.log(1)}
      else{
        for( var j=n;j>1;j--){
          i*=j
        }
        console.log(i)
      } 
    }
    fac(5)     //  120
    
    7、以下のコードは何を出力しますか?
    function getInfo(name, age, sex){
            console.log('name:',name);
            console.log('age:', age);
            console.log('sex:', sex);
            console.log(arguments);
            arguments[0] = 'valley';
            console.log('name', name);
        }
    
    getInfo('   ', 2, ' ');
    getInfo('  ', 3);
    getInfo(' ');
    
    注意:
  • consone.log(...)は、括弧内の戻り値ではなく、括弧内のすべての表現の値を出力します.
  • は、関数にパラメータが入ったときに、順番に入ってきます.自動的には認識されません.パラメータが入っていない場合はundefinedです.var fnName = function () {…};   //
  • に相当します.
    function getInfo(){
                arguments[0]='   '
                arguments[1]=2
                arguments[2]=' '
                console.log('name:','   ')     
                console.log('age:', 2)
                console.log('sex:', ' ')
                console.log(['   ',2,' '])
                arguments[0] = 'valley'
                console.log('name', 'valley')
    }
    getInfo()
    
    /*  :
    name:    
    age: 2
    sex:  
    ["   ", 2, " "]
    name valley
    */
    
    get Info('小谷',3);に相当する
    function getInfo(){
                arguments[0]='   '
                arguments[1]=3
                arguments[2]=undefined
                console.log('name:','   ')     
                console.log('age:', 3)
                console.log('sex:', undefined)
                console.log(['   ',3])
                arguments[0] = 'valley'
                console.log('name', 'valley')
    }
    getInfo()
    
    /*  :
    name:    
    age: 3
    sex: undefined
    ["   ", 3]
    name valley
    */
    
    get Info('男')に相当する
    function getInfo(){
                arguments[0]=' '
                arguments[1]=undefined
                arguments[2]=undefined
                console.log('name:',' ')     
                console.log('age:', undefined)
                console.log('sex:', undefined)
                console.log([' '])
                arguments[0] = 'valley'
                console.log('name', 'valley')
    }
    getInfo()
    
    /*  :
    name:  
    age: undefined
    sex: undefined
    [" "]
    name valley
    */
    
    8、関数を書いて、パラメータの平方和を返しますか?
    function sumOfSquares(){
       }
       var result = sumOfSquares(2,3,4)
       var result2 = sumOfSquares(1,3)
       console.log(result)  //29
       console.log(result2)  //10
    
    考え方を答えます:すべての伝来のパラメーターを遍歴して、それらの平方和を求めます.遍歴の方法によって、違った書き方があります.
  • forサイクル方法
  • ループを実行するたびに、array.lengthの値を確認します.属性は読む部分変数より遅くなります.特にarrayに保存されているのはDOM元素です.
    function sumOfSquares(){
        var sum=0
        for(var i=0;i
  • for-iサイクル方法
  • for-i nはarrayの各属性を分析する必要があります.この操作の性能はオーバーヘッドが大きいです.
    function sumOfSquares(){
        var sum=0
        for(i in arguments){
            sum+=arguments[i]*arguments[i]
        }
        return sum
    }
      var result = sumOfSquares(2,3,4)
      var result2 = sumOfSquares(1,3)
      console.log(result)  //29
      console.log(result2)  //10
    
  • 配列の長さを先に調べ、局所変数に保存すると、サイクルの速度が大幅に高くなります.
    function sumOfSquares(){
        var sum=0
        var length=arguments.length
        for(var i=0;i
  • ですが、もっと速くしてもいいです.サイクル終了条件が比較演算を必要としない場合、サイクルの速度はさらに速くなります.
  • は配列の下付きを0に逓減させ、循環終了条件はiが0かどうかを判断するだけでよい.サイクルインクリメントとループ終了条件が結合されているので、より簡単なwhileサイクル
  • と書くことができる.
    function sumOfSquares(){
        var sum=0
        var i=arguments.length
        while(i--){
            sum+=arguments[i]*arguments[i]
        }
        return sum
    }
    var result = sumOfSquares(2,3,4)
    var result2 = sumOfSquares(1,3)
    console.log(result)  //29
    console.log(result2)  //10
    
    9、下記のコードの出力ですか?なぜですか
    console.log(a);
    var a = 1;
    console.log(b);
    
    変数アップの原則により、上記のコードは
    var a
    console.log(a)    //  undefined
    a=1
    console.log(b)    //  :Uncaught ReferenceError: b is not defined
    
  • 理由:先に変数aを宣言しましたが、aはコピーされていませんので、出力aはundefinedを得ます.b宣言なしに直接呼び出しますので、エラーとします.
  • 10、以下のコードの出力ですか?なぜですか
    sayName('world');
        sayAge(10);
        function sayName(name){
            console.log('hello ', name);
        }
        var sayAge = function(age){
            console.log(age);
        };
    
    出力:getInfo(' ', 2, ' '); "hello" "world"
  • 理由:関数宣言は自動的に向上しますが、関数表現はできません.Uncaught TypeError: sayAge is not a functionは正常に実行されます.sayName('world');は関数sayAge(10);を呼び出すことができますが、sayAgeは変数であり、関数宣言を与えていないので、まだ関数ではないので、エラーが発生しました.
  • 11、次のコードから何を出力しますか?なぜですか
    var x = 10
    bar() 
    function foo() {
      console.log(x)
    }
    function bar(){
      var x = 30
      foo()
    }
    
    出力:10
  • 理由:関数のスコープは、その定義時に存在するスコープと関連しており、呼び出し時に存在するスコープとは無関係である.sayAgeでは、グローバルスコープ内のbar()を呼び出すことができ、foo()foo()の局所変数x(x=30)にアクセスできず、グローバルスコープ内のグローバル変数x(x=10)にのみアクセスできるので、出力10は出力される.
  • 12、次のコードから何を出力しますか?なぜですか
    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      function foo(){
        console.log(x) 
      }
      foo();
    }   
    
    出力:30
  • の原因:変数の検索は近くの原則で、var定義の変数を探しに行きます.近くに見つけられない場合は外層を探しに行きます.関数領域は全局所に優先され、局所変数xは大域変数xを上書きするので、出力30を出力します.
  • 13、以下のコードは何を出力しますか?作用するドメインチェーンの検索過程の疑似コードを書き出します.
    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      (function (){
        console.log(x)
      })()
    }
    //30
    
    疑似コードは以下の通りです
    globalContext = {
      AO: {
        x: 10
        bar: function
      }
      Scope: null
    }
    bar.[[scope]] = globalContext.AO
    
    barContext = {
      AO: {
        x: 30
        (no-name): function
      }
      Scope: bar.[[scope]] //globalContext.AO
    }
    (no-name).[[scope]] = barContext.AO
    
    (no-name)Context = {
      AO: {}
      Scope: (no-name).[[scope]] //barContext.AO
    }
    
    呼び出し(no-name)()をする時、まずコンテキストのAOから探します.barの[scope]から見つけられません.x=30が見つかったら呼び出します.
    14、以下のコードは何を出力しますか?作用ドメインチェーンの検索過程の疑似コードを書き出します.
    var a = 1;
    
    function fn(){
      console.log(a)     //  undefined
      var a = 5
      console.log(a)     //  5
      a++
      var a
      fn3()
      fn2()
      console.log(a)     //  20
      function fn2(){
        console.log(a)     //  6
        a = 20
      }
    }
    
    function fn3(){
      console.log(a)     //  1
      a = 200
    }
    
    fn()
    console.log(a)     //  200
    
    疑似コードは以下の通りです
    globalContext = {
      AO: {
        a: 1
        fn: function
        fn3: function
      }
      Scope: null
    }
    fn.[[scope]] = globalContext.AO
    fn3.[[scope]] = globalContext.AO
    //  fn()
    fnContext = {
      AO: {
        a: undefined
        fn2: function
      }
      Scope:  fn.[[scope]] //globalContext.AO
    }
    //  console.log(a)     //  undefined
    //a = 5
    fnContext = {
      AO: {
        a: 5
        fn2: function
      }
      Scope:  fn.[[scope]] //globalContext.AO
    }
    fn2.[[scope]] = fnContext.AO
    //  console.log(a)     //  5
    //  a++
    fnContext = {
      AO: {
        a: 6
        fn2: function
      }
      Scope:  fn.[[scope]] //globalContext.AO
    }
    fn2.[[scope]] = fnContext.AO
    //  fn3()
    fn3Context = {
      AO: {}
      Scope:  fn3.[[scope]] //globalContext.AO
    }
    //  console.log(a)     //  1
    //a=200   a  200
    //  fn2()
    fn2Context = {
      AO: {}
      Scope:  fn2.[[scope]] //fnContext.AO
    }
    //  console.log(a)     //  6
    //a=20fn a  20
    //  console.log(a)     //  20
    //  console.log(a)     //  200
    
    最終出力
    undefined
    5
    1
    6
    30
    200