script#02-関数ガイド


有効範囲


有効範囲は変数の寿命です

グローバル変数とゾーン変数


変数を宣言するときはvarを加えることに慣れなければならない.グローバル変数を使用する必要がある場合は、その理由を明確にするときに使用してください.
var vscope = 'global';
function fscope(){
  var vscope ='local';	//이 한 줄이 없다면 global을,
  alert(vscope);	//local을 보여준다.
}
fscope();
同じ名前の領域変数とグローバル変数が同時に定義されている場合は、領域変数が優先されます.

グローバル変数の使用


グローバル変数を使用する必要が避けられない場合は、オブジェクトをグローバル変数として作成し、オブジェクトのプロパティを使用して変数を管理します.
MYAPP = {}
MYAPP.calculator = {
  'left' : null,
  'right' : null
}

MYAPP.coordinate = {
  'left' : null,
  'right' : null
}

MYAPP.calculator.left = 10;
MYAPP.calculator.right = 20;

function sum(){
    return MYAPP.calculator.left + MYAPP.calculator.right;
}

document.write(sum());	//30
グローバル変数を使用したくない場合は、匿名関数を呼び出します.
次に、論理をモジュール化する一般的な方法を示します.
(function(){
    var MYAPP = {}
    MYAPP.calculator = {
        'left' : null,
        'right' : null
    }
    MYAPP.coordinate = {
        'left' : null,
        'right' : null
    }
    MYAPP.calculator.left = 10;
    MYAPP.calculator.right = 20;
    function sum(){
        return MYAPP.calculator.left + MYAPP.calculator.right;
    }
    document.write(sum());
}())
(function(){함수 내용})();匿名関数の使用

値としての関数とコールバック


関数の用途


Javascriptでは、関数もオブジェクトです.一種の価値と見なすべきだ.Javascriptの関数は値です.
function a(){}

//이는 다음과 같이 표현할 수 있다.
var a = function(){}

//또는
a = {
  b:function(){	//함수는 객체 안에 저장될 수 있다. 함수가 값이기 때문이다.
  }
};
c++では、関数ポインタを使用して関数を渡しますが、ここでは値として渡します.
function call(func, num){
  return func(num)
}

function increase(num){
  return num+1
}

document.write(call(increase,1));
func[mode]およびcall('plus')(2,1)
function call(mode){
  var funcs = {
    'plus' : function(left, right) {return left + right},
    'minus' : function(left, right) {return left - right}
  }
  return funcs[mode];
}

document.write(call('plus')(2,1));
言いたいことは配列に関数を入れることができます.関数も値と見なされるから!
var process = [
  function(input) { return input+10; },
  function(input) { return input*input;},
  function(input) { return input/2}
 ];

var input = 1;
for (var i = 0 ; i < process.length; i++){
  input = process[i](input);
  document.write(input+"<br/>");
}

ダイヤルバック


関数を値の特性として利用し,関数を関数のパラメータとして伝達することができる.
var numbers = [20,10,9,8,7,6,5,4,3,2,1];
//numbers.sort(); 	//[1, 10, 2, 20, 3, 4...]가 나온다.

function sortNum(a, b){
  return a-b;	//a-b : 오름차순, b-a : 내림차순
}

console.log(numbers.sort(sortNum));
sort.()は(組み込み、構築)メソッドであり、これを行うとUnicode順にソートされます.したがって、正しくソートするために、関数sortNumが入力パラメータとしてここに渡される.
ここで、sortNumはcallback関数となる.
注意-sort関数

非同期処理

  • 動機:要求と結果が同時に発生した場合、要求がどのくらいの時間を要しても、要求された場所で結果を与えなければならない.デザインはシンプルで直感的ですが、結果が出るまで何もできませんでした.
  • 非同期処理:要求と結果が同時に発生しない.モチベーションよりも複雑ですが、結果を出すのに時間がかかっても、この時間内に他のタスクを実行して効率的なリソース管理を実現できます.
  • 注意-同期と非同期の説明
    注意-Ajax Ajax - Asynchronous javascript and XML
    次のデータ・ソース:json.jsがあるって言ったでしょ
    {"title":"JavaScript","author":"egoing"}
    私はあなたに電話を返しに来たのです.重要なのは、関数をパラメータとして渡すことです.
    <!DOCTYPE html>
    <html>
    <head>
    <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
    </head>
    <body>
    <script type="text/javascript">
        $.get('./datasource.json.js', function(result){
            console.log(result);
        }, 'json');
    </script>
    </body>
    </html>

    エンクロージャ


    closureとは、内部関数が外部関数にアクセスできる脈絡を指す.

    内部関数と外部関数


    関数1で使用されている関数2の場合のみ、関数1に関数2を宣言して、読みやすさを向上させ、管理を容易にします.
    function outter(){
      function inner(){
        var title = "code";
        alert(title);
      }
      inner();
    }
    
    outter();	//code
    ただし、以下のコードがあれば、
    function outter(){
      var title = "code";
      function inner(){
        alert(title);
      }
      inner();
    }
    
    outter();	//code
    当初、innerのtitleはinnerで値を検索したが、関連変数がないことが分かった後、外部関数outterで値を検索する.
    内部関数から外部関数にアクセスする領域変数

    closure


    すなわち,内部関数は外部関数の領域変数にアクセスでき,外部関数の実行が完了して外部関数が消失した後でも,内部関数は外部関数の変数にアクセスできる.
    function outter(){
        var title = 'code';  
        return function(){ alert(title); } //내부함수를 리턴하고 있는 것. 이름 없는 내부함수
    }
    inner = outter(); // inner라고 하는 변수에 리턴받은 내부함수의 내용이 들어가는 것
    inner(); 
    outter関数が戻った瞬間、outter関数の生命は終わった.死んだもの.しかし,inner関数を呼び出す瞬間にreturnのfunction(){ alert(title); }titleを実行しなければならず,ここでのtitleは既に死んだoutter関数の領域変数であり,原則として取得できない.ただし、titleの値はcodeである.これで終わりです.死にも近づく.
    function factory(title) {
      return {
        //여기서 title은 factory 함수의 입력인자의 title로 가져온다.
        get_title : function() { return title; },
        set_title : function(_title) {
          if (typeof(_title) === 'String') {
            title = _title;
          }
          else {
            alert ('제목은 문자열이여야 합니다.');
        }
      }
    }
    
    fav = factory('The Grnd Bdpst Htl');
    matrix = factory('Matrix');
    
    console.log(fav.get_title());		//The Grnd Bdpst Htl
    console.log(matrix.get_title());	//Matrix
    
    fav.set_title('공각기동대');
    console.log(fav.get_title());		//공각기동대

  • オブジェクトのメソッドでもモジュールを使用できます.set titleとget titleは、外部関数factoryのパラメータ値として渡される領域変数titleを使用します.

  • 同じ外部関数で作成された内部関数またはメソッドは、外部関数の領域変数を共有します.

  • JAvascriptは基本的にプライベート属性をサポートしていませんが、モジュールのこれらの特性はプライベート属性を使用できます.
  • closureに関連する一般的なエラー


    注意-youtube link
    var arr = []
    for(var i = 0; i < 5; i++){
      arr[i] = function(){
        return i;
      }
    }
    
    for(var index in arr) {
      console.log(arr[index]());
    }

    ここで結果は5 5 5 5 5 5 5です.
    i値は外部変数の値ではないためです.この関数を内部関数とし、その関数を囲む外部関数を作成します.
    var arr = []
    for(var i = 0; i < 5; i++){
        arr[i] = function(id) {
            return function(){
                return id;
            }
        }(i);	//i를 받아 id로 넣는다. 전달받은 id는 곧바로 return 되어 arr[i]에 저장된다.
    }
    
    for(var index in arr) {
        console.log(arr[index]());
    }

    関数呼び出し

    function(){ return i; } , Function.applyこのようにしてFunction.callを呼び出すこともできるが、sum();を呼び出すこともできる.
    function sum(arg1, arg2){
      return arg1 + arg2;
    }
    
    alert(sum.apply(null, [1, 2]))
  • sum.apply(null);:最初のパラメータは、関数(および)が実行する脈絡です.
  • null:2番目のパラメータは、関数のパラメータに順次置換される配列です.
  • function sum() {
      var _sum = 0;
      for (id in this) {
        if (typeof this[name] !== 'function')
          _sum += this[id];
        //document.write("this "+ id + "\n");
        //여기서 id는 val1, v1... 들
      }
      return _sum;
    }
    o1 = {val1:1, val2:2, val3:3, sum:sum}
    o2 = {v1:10, v2:50, v3:100, v4:25, sum:sum}
    
    console.log(sum.apply(o1))	//6
    console.log(sum.apply(o2))	//185
    [1, 2]では、o 1はapplyのパラメータであり、sum関数のthisである.(== sum.apply(o1) )
    applyの最初のパラメータは関数が動作する脈絡である.sum.apply(o 1)関数sumをオブジェクトo 1とする方法sumを呼び出してsumを削除する
    o1.sum = sum; 
    console.log(o1.sum());	//결과로 sum함수의 모든 내용이 나온다.
    delete o1.sum();
    ここで、関数sumをオブジェクトo 1として作成する方法を呼び出してsumを削除する.
    関数sumでは、この値はグローバルオブジェクトではなくo 1であることを意味します.