IT이야기

console.log.bind (콘솔)

cyworld 2021. 5. 2. 10:58
반응형

이 진술은 무엇을합니까? console.log.bind (콘솔)


JavaScript를 사용하고 있으며 문에 문제가 있습니다.

console.log.bind(console)

이 진술이 실제로 무엇을하는지 알려주세요. 나는 이것을 여러 번 적용했지만 아무것도하지 않았습니다.


JavaScript에서 this함수 호출은 함수가 호출 되는 방식에 따라 결정됩니다 (일반 함수에 대해서는 아래 * 참조). 객체 속성을 검색하는 표현식의 일부로 호출되는 경우 (예 :에서 속성 검색 작업의 일부로 foo.bar()호출 ) 함수를 호출하는 동안 속성이 가져온 객체로 설정됩니다.bar()foothis

console.log와 같이 더 짧은 형식을 원한다고 가정합니다 f. 다음과 같이 할 수 있습니다.

var f = console.log; // <== Suspect!

...하지만 log함수 가 호출 중에 객체 this참조하는 데 의존하는 경우 참조 하지 않으므로 console호출 f("Message here")이 작동 this하지 않습니다 console.

Function#bind그 상황을위한 것입니다. 호출 될 때 this사용자가 제공 한 값 으로 설정된 원본을 호출하는 새 함수를 만들 수 있습니다 . 그래서

var f = console.log.bind(console); // Still suspect, for a different reason

... 해야한다 , 이론적으로, 당신에게 기능을 제공, f당신은 콘솔에 로그인 할 때 호출 할 수 있습니다.

예외 : console.log(및 alertgetElementById) 같은 호스트 제공 함수 는 "실제"JavaScript 함수일 필요는 없으며 (최신 브라우저에서는 이러한 기능이 거의 비슷하거나 최소한 매우 유사하지만) 모든 기능을 가질 필요는 없습니다. , inculding bind. 따라서 해당 라인에서 오류가 발생하면 해당 라인을 사용중인 엔진이 bind해당 console.log기능을 지원하지 않는 것일 수 있습니다 .

그렇다면 "호스트 제공 기능"이란 무엇입니까? 사양에 명시 적으로 정의되지 않은 모든 함수 는 언어 JavaScript의 일부입니다 . 다시 말하지만, 브라우저 관련 기능인 alertor console.log등과 같은 브라우저에서 .

라인이 문제를 일으킬 수있는 두 가지 이유를 생각할 수 있습니다.

  1. 위 : console.log실제 기능을 만들지 않는 JavaScript 엔진을 사용하고 있습니다.

  2. 개발자 도구를 닫은 상태에서 IE에서 위의 줄을 사용하고 있습니다. IE에서 개발 도구가 열려 있지 않으면 console개체가 정의되지 않았으므로 해당 줄은 ReferenceError.

최종 목표가 호출 할 수있는 함수 (예 f("Message here"): for )를 얻는 것이라면 console.log위의 # 1과 # 2를 모두 처리하는 방법은 다음과 같습니다.

function f(item) {
    if (typeof console != "undefined" && console.log) {
        console.log(item);
    }
}

이렇게하면 하나의 항목 만 제공 할 수있는 반면 console.log여러 항목 ( console.log("this", "that", "and the other")) 을 제공 할 console.log있지만 실제 JavaScript 함수가 아닐 수있는 경우 는 없을 수 있으므로 Function#apply래핑하기가 매우 어렵습니다.

이제 거기에 무엇이 있는지 볼 수 있는 한 동일한 출력을 얻는 데 신경 쓰지 않는다면 ( 함수에 전달 된 모든 인수에 대한 내장 식별자)를 사용하십시오. 그러나 정확한 출력을 복제하려면 다음과 같은 작업을 수행하게됩니다.console.log("this", "that", "and the other")console.log(arguments);arguments

function f() {
    var a = arguments;

    if (typeof console != "undefined" && console.log) {
        if (console.log.apply) {
            // It has Function#apply, use it
            console.log.apply(console, arguments);
        } else {
            // Ugh, no Function#apply
            switch (a.length) {
                case 0: console.log(); break;
                case 1: console.log(a[0]); break;
                case 2: console.log(a[0], a[1]); break;
                case 3: console.log(a[0], a[1], a[2]); break;
                case 4: console.log(a[0], a[1], a[2], a[3]); break;
                case 5: console.log(a[0], a[1], a[2], a[3], a[4]); break;
                default:
                    throw "f() only supports up to 5 arguments";
            }
        }
    }
}

... 그냥 못 생겼습니다.


* ES5는 바인딩this 을 통해 값이 첨부 된 함수바인딩 된 함수를 추가 했습니다.

// Normal function
function foo() {
    console.log(this.name);
}

// Create a bound function:
var f = foo.bind(someObject);

어떻게 호출하든 상관 없습니다 . 설정된 상태로 f호출 됩니다 .foothissomeObject

* ES2015 (일명 ES6)는 화살표 기능을 추가했습니다 . 화살표 기능, this되어 있지 함수가 호출 설정 방법; 대신 함수 this는 생성 된 컨텍스트에서 상속 됩니다.

// Whatever `this` is here...
var f = () => {                             // <== Creates an arrow function
    // Is what `this` will be here
};

화살표 함수는 Array#forEach객체 메서드 내에서 다음과 같은 작업을 할 때 정말 편리 합니다.

this.counter = 0;
this.someArray.forEach(entry => {
    if (entry.has(/* some relevant something */)) {
        ++this.counter;
    }
});

TJ Crowder의 답변은 console.log출력 리디렉션과 관련된 문제를 설명하고 해결하는 데 도움이 되었지만 "no Function # apply"사례에 대한 그의 솔루션은 많은 사용 사례에서 임의로 제한되는 것처럼 보였습니다.

좀 더 깔끔하고 기능적인 코드를 다음과 같이 다시 작성했습니다.

function f() {
    var a = arguments;

    if (typeof console != "undefined" && console.log) {
        if (console.log.apply) {
            // It has Function#apply, use it
            console.log.apply(console, arguments);
        } else {
            // Ugh, no Function#apply
            var output = '';
            for (i=0;i<arguments.length;i++) {
                output += arguments[i] + ' ';
            }
            console.log(output);
        }
    }
}

console.log공백으로 인수를 분리하므로 여기에서도 복제했습니다. 이에 대한 주요 제한은 개체 인 인수를 처리하지 않는다는 것입니다. 필요한 경우이를 문자열화할 수 있습니다.


이 문제에 대한 빠른 업데이트는 더 이상 콘솔을 자체에 바인딩 할 필요가없는 것 같습니다.

Chromium은 console개체 에 대한 몇 가지 깊은 변경 사항을 배포하기 시작했으며 이제는 이미 자체에 바인딩되어 있습니다. https://chromium.googlesource.com/chromium/src.git/+/807ec9550e8a31517966636e6a5b506474ab4ea9

또한 다른 모든 브라우저가이 경로를 따랐던 것 같습니다 (최신 버전의 Firefox 및 Node에서 테스트 됨).

이전 브라우저와 호환되어야한다면 여전히 콘솔을 수동으로 바인딩해야하지만 디버그를 위해 이제 .bind(console):)를 생략 할 수 있습니다.


다른 답변에서 언급했듯이 console.error함수를 오류 처리기로 제공 하고을 본문 내의 값으로 bind(console)사용합니다 . 그렇지 않으면 전역 개체 ( 브라우저에서)로 설정되고 호출이 실패합니다. 여기에 잘 설명되어 있습니다 .consolethisthiswindow

종종 Promise오류 처리 에서이를 확인할 수 있습니다 (예 : Angular 2 빠른 시작).

System.import("unmarshaller/Unmarshaller.js").then(null, console.error.bind(console));

주제에서 벗어난 부분 :

오류를 사전 처리하기 위해 고유 한 처리기를 만들 수 있습니다. 위의 예에서 "Error loading Unmarshaller.js" 만 알려 주기 때문에 콘솔에 console.error보기 흉하게 인쇄 됩니다 . 그리고 다른 오류는 .ErrorSystemJSoriginalErr

래핑을 해제 할 사용자 지정 처리기를 만듭니다.

function handleError(e) {
    if (e.originalErr)
        throw e.originalErr;
    throw e;
}

System.import("unmarshaller/Unmarshaller.js").then(null, handleError);

No need for .bind(), and will give you the Error originally thrown, like:

Error: Given object doesn't specify "w:winduptype" and no target class given:
[{"w:winduptype":["FileResource","ArchiveModel:","WarArchiveModel"], ...

ReferenceURL : https://stackoverflow.com/questions/28668759/what-does-this-statement-do-console-log-bindconsole

반응형