Javascript_Study_0131( what is Argument, This , Apply Method , Call vs Bind vs Apply method ?)

12667 ワード

1. argument


「パラメータ」と「パラメータ」の違い.
// a라는 함수, arg1 이라고 하는 매개변수가 있다고 한다면 
function a  ( arg1 ) {
	
}

# 1은 인자 : argument
a(1)

즉, arg1 : parameter > 매개변수
1 : argument > 인자 ( 들어가는 값 )

function sum( ) {
	let i  = 0 
    for( let i = 0; i < arguments.length; i ++ ){
    	console.log(arguments[i])
    }
}

sum(1,2,3,4)

Javascript는 매우 관대한 언어이다.
sum 이라는 함수를 보면, 지금은 매개변수가 없다. 

그런데 인자 1, 2, 3, 4 총 4개를 전달했다.
JS는 함수의 매개변수를 정의하지 않은 경우에도, 
인자의 수를 마음대로 지정할 수 있다.
매개변수가 3개 인데, 인자가 1개 등, 수가 달라도 괜찮다. 

ではsum関数の「パラメータ」は何でしょうか.
sum関数で変数として宣言されていません.
なぜ文案でそのように使えるのでしょうか.
いわゆる論争.
指定された、特殊な名前の変数名.
ここにはargumentsという「類似配列、オブジェクト」が含まれています.
この案では.
ユーザが渡す「パラメータ」は、パラメータと呼ばれる類似配列に含まれます.
パラメータによって、ユーザーは渡されたパラメータにアクセスできます.
Argumentsオブジェクトの使い方は配列と似ています.
arguments.lengthと同様に、配列方法を使用できます.

2. this


thisの値は関数を呼び出す方法によって決まります
「bindという関数もあります.呼び出し方法に関係なくバンドルされます.」

1.例

someone.whoAmI() // 자신을 호출한 somone이라는 객체가 나온다

        var myWhoAmI = someone.whoAmI;
        /*
        분명히 위의 코드를 통해서 
        someone.whoAmI() 가 myWhoAmI 에 할당되었으니
        같은 값이 출력될 것이라고 생각했으나

        ex. result : window ~~
        가 호출된 것을 확인할 수 있다...?

        왜 ? 호출하는 방법이 달라졌기 때문이다.
        this....는 누가 호출했냐 ! 이다

        somone.whoAmI() 의 경우, 
        whoAmI()를 호출한 애는, 
        someone !
        '.' 이 중요하다 !

        someone. 인 것이다 ! 

        반면, myWhoAmI() 의 경우 ,
        글로벌에 존재하고
        글로벌은 window 에 의해 호출되기 때문에
        사실상 window가 호출하는 셈이다. 
        브라우저가 그냥 실행한 것이다. 

        */
        myWhoAmI()

2.例(html elem)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="btn">btn</button>
    <script>
        var someone = {
            name : 'codejong',
            whoAmI : function(){
                console.log(this)
            }
        }

        someone.whoAmI() // 자신을 호출한 somone이라는 객체가 나온다

        var myWhoAmI = someone.whoAmI;
        /*
        분명히 위의 코드를 통해서 
        someone.whoAmI() 가 myWhoAmI 에 할당되었으니
        같은 값이 출력될 것이라고 생각했으나

        ex. result : window ~~
        가 호출된 것을 확인할 수 있다...?

        왜 ? 호출하는 방법이 달라졌기 때문이다.
        this....는 누가 호출했냐 ! 이다

        somone.whoAmI() 의 경우, 
        whoAmI()를 호출한 애는, 
        someone !
        '.' 이 중요하다 !

        someone. 인 것이다 ! 

        반면, myWhoAmI() 의 경우 ,
        글로벌에 존재하고
        글로벌은 window 에 의해 호출되기 때문에
        사실상 window가 호출하는 셈이다. 
        브라우저가 그냥 실행한 것이다. 

        */
        myWhoAmI()


        // html 상의 버튼을 클릭할 때
        var btn = document.getElementById('btn')
        /*

        예상한 결과는
        {
            name : 'codejong',
            whoAmI : f
        }

        실제 결과는
        <button class="btn">btn</button>
        즉, html element가 나오는 것이다. 

        자. 자세히 보면, 
        여기서는 somone이 whoAmI 를 호출한 것이 아니다.
        그저 somone.whoAmI()라는 함수를 넘긴 것 뿐이다.

        그리고 그 함수를 꺼내서 버튼한테 준것이고
        버튼을 누르면, 그 함수를 실행하라고 한 것.

        즉, 호출한 것은, "버튼"인 것이다. 
        btn.addEventListener('click', someone.whoAmI)
        
        결국 
        "호출한 놈 == THIS" ! 
        */
        btn.addEventListener('click', someone.whoAmI)

        // 'someone'을 this라고 하겠다는 것이다.
        // 즉, bindedWhoAmI는 someone을 무조건 this로 받겠다 !
        let bindedWhoAmI = myWhoAmI.bind(someone)
        /*
        < 실행결과 >
         {
            name : 'codejong',
            whoAmI : f
        }
        */
        console.log(bindedWhoAmI())

    </script>
</body>
</html>

3. Call vs Bind vs Apply

let bob = function(num, str){
    console.log('bob', num, str, this)
    return true
}

let bill = {
    name : 'Bill Murray',
    movie : 'Lost in Translation',
    myMethod : function(fn){
        // fn : passed in arg

    }
}
if code is constructed like above ,

> bill.myMethod(bob)
we will see
'''
bob undefined undefined
Window ~~//since 'this' refers to 'Window' which calls bob !!
//it's not 'bill' that calls bob !
//if you see the 'myMethod' function,
//fn() >> it's not bill.fn()
//fn() >> it's just called by 'window' object
'''

call, apply_1)


when we use
'call' , 'apply' , 'bind' method ,
we have to consider the 'context' in which
the function is running,
'''
_bob.call(bill , 2, 'goodbye' )
'''
I want bob function to run !

1st arg : what is 'context' ?


'bill' object is a context for 'bob' function to run

after arg :


we can list out any kinds of args, we want to pass in

result


'''
bob 2 goodbye
{ name : Bill Murray , movie : 'Lost in Transitor', myMethod : f }
'''
as you can see,
'this' is now pointing the 'bill' object, not that 'Window'
which means that,
'context' becomes 'this'
'''
bob.apply(bill, [ 2, 'good bye'] )
'''
we will see the same result !

call, apply _2)


what if we want to run below code ?
'''
bill.myMethod(bob, 4, 'ciao' ) ??
'''
we need to revise the code as below
'''
let bob = function(num, str){
console.log('bob', num, str, this)
return true
}
let bill = {
name : 'Bill Murray',
movie : 'Lost in Translation',
myMethod : function(fn){
//fn : passed in arg
fn.apply(bill, [ arguments[1], arguments[2] ] )
//same : fn.apply( bill , n, s )
}
}
'''
so we are saying that,
'fn' that runs in 'bill' context,
will take 2args which are
'arguments[1]' , 'arguments[2]'

bind


it does pretty much the same thing as 'call' or 'apply' function.
unique characteristic of bind is that,
you can save it in a variable to use it later on.
'''
bob.bind(bill, 5, 'hasta la vista' )
'''
above code itself, does nothing
why ?
in contrast to 'call' or 'apply' method,
'bind', prepares the function to be called later on ,
instead of running it right away,
it passes back the copied array
'''
let fred = bob.bind(bill, 5, 'hasta la vista' )
fred()
'''