JS 함수의 'this'에 기본값이 있습니까?

부인 성명



JS에는 이것에 대한 1000000개의 기사가 있습니다. 하나 더 추가해도 괜찮을 것 같아요.

Array.prototype.map의 두 번째 매개변수



최근에 배열 프로토타입의 .map() 메서드에 대한 MDN 페이지를 확인하고 한 단락 마녀를 만났는데 내 관심을 끌었습니다.



여기서 thisArg는 .map() 메서드의 두 번째 매개변수입니다. (1)

두 번째 문장은 "그렇지 않으면 정의되지 않은 값이 this 값으로 사용됩니다."라고 말합니다. 따라서 빠른 테스트를 수행하고 .map() 내부에 콜백만 전달해 보겠습니다.

[1,2,3].map(function(){console.log(this)})
// globalObject
// globalObject
// globalObject


콜백이 실행될 때 이 값이 전역 객체이고 정의되지 않은 것이 아니기 때문에 혼란스러워 보입니다. 실제로 콜백이 엄격하지 않은 모드에서 실행되기 때문에 예상됩니다. 그렇다면 어구가 정의되지 않은 이유는 무엇입니까?

그럼에도 불구하고 특히 우리가 "callbackFn에 의해 궁극적으로 관찰 가능한 이 값"이라는 줄에 주의를 기울이면 이 문구는 의미가 있습니다.

그렇다면 "궁극적으로 관찰 가능하다"는 것은 무엇을 의미합니까?

함수의 기본값은 this



가장 간단한 함수를 만들고 .apply() 메서드로 호출해 봅시다. .apply() 메서드를 사용하면 이 값을 명시적으로 설정할 수 있으며 이를 정의되지 않은 것으로 설정하겠습니다.

function f (){
   console.log(this)
}

f.apply(undefined)
// globalObject


따라서 함수 f는 궁극적으로 우리가 명시적으로 전달하는 정의되지 않은 값이 아니라 this에서 globalObject 값을 관찰한다는 결론을 내릴 수 있습니다. 제 생각에는 이러한 동작을 기본 함수 매개변수와 비교할 수 있습니다.

function f(a=globalObject){
    console.log(a)
}

f();


사양 시간!



이제 어떤 사례도 놓치지 않도록 ES specification을 열 차례입니다.

나는 당신의 삶을 더 쉽게 만들고 싶습니다. 그래서 이 값의 기본값을 담당하는 추상 연산OrdinaryCallBindThis이 있습니다. 여러 단계가 있지만 그 중 2개가 주요 단계입니다.



그림에서 2가지 변수에 주목합시다.

  • thisArgument - 함수에서 전달된 값입니다.

  • thisValue - 함수에 의해 궁극적으로 관찰 가능한 값입니다.

  • 5단계는 함수가 엄격 모드에서 호출되면 thisValue가 thisArgument가 되고 이에 대한 기본값은 적용할 수 없다고 말합니다.

    function f (){
       'use strict'
       console.log(this)
    }
    
    f.apply(undefined)
    // undefined
    


    6단계는 함수가 비엄격 모드에서 호출되고 thisArgument가 정의되지 않거나 null이면 thisValue(이 내부 함수의 실제 값)는 globalObject(그림의 globalEnv.[[GlobalThisValue]]는 전역 객체일 뿐임)라고 말합니다. .

    function f (){
       console.log(this)
    }
    
    f.apply(undefined)
    f.apply(null)
    // globalObject
    // globalObject
    


    따라서 null 값도 globalObject 기본값으로 대체됩니다.

    또한 non-strict 모드에도 유효한 6.b를 살펴볼 가치가 있습니다. thisArgument의 기본 값에 대한 래퍼 개체(문자열, 숫자 등)를 생성하는 toObject() 작업 호출이 있습니다.

    function f (){
       console.log(this)
    }
    
    f.apply('')
    // String {''}
    


    따라서 함수의 this 값은 항상 non-strict 모드의 객체 유형입니다.

    결론



    JS에서 함수를 호출할 때마다 this 값을 전달합니다. f()와 같은 함수를 호출하더라도; 여전히 암시적으로 정의되지 않은 값을 전달합니다. 엄격 모드 함수는 수정 없이 이 값을 받아들입니다. 엄격하지 않은 함수는 정의되지 않은 값과 null 값을 전역 개체로 대체하고 개체의 모든 기본 값을 변환합니다.

    다음 면접관의 마음을 얻기 위해 그 결론을 자유롭게 사용하십시오.

    추신
    setTimeout 콜백에서 이 값에 대한 나의 오래된 것이 하나 있습니다. 브라우저 콜백에서 이것은 항상 창이며 엄격/비엄격 모드에 의존하지 않습니다. 그 이유는 setTimeout 메서드는 콜백을 실행할 때 undefined가 아닌 window 객체를 전달하기 때문입니다. 엄격하지 않은 기본 대체는 thisArgument가 정의되지 않았거나 null이 아니므로 작동하지 않습니다.

    (1) - Array.prototype.map() 메서드에는 두 번째 선택적 매개변수가 있습니다.

    // Callback function
    map(callbackFn)
    map(callbackFn, thisArg)
    


    두 번째 매개 변수는 콜백 함수에 대한 .bind() 메서드 대신 사용할 수 있습니다.

    좋은 웹페이지 즐겨찾기