developer tip

(1, eval) ( 'this') 대 eval ( 'this') JavaScript에서?

optionbox 2020. 10. 10. 09:57
반응형

(1, eval) ( 'this') 대 eval ( 'this') JavaScript에서?


JavaScript Patterns 를 읽기 시작 했는데 일부 코드가 혼란 스러웠습니다.

var global = (function () {
    return this || (1, eval)('this');
}());

내 질문은 다음과 같습니다.

Q1 :

(1, eval) === eval?

왜 그리고 어떻게 작동합니까?

Q2 : 왜 그냥

var global = (function () {
    return this || eval('this');
}());

또는

 var global = (function () {
    return this;
}());

(1,eval)오래된 것과 평범한 차이 eval는 전자가 이고 후자가 lvalue라는 것입니다. 다른 식별자라면 더 분명 할 것입니다.

var x;
x = 1;
(1, x) = 1; //  syntax error, of course!

그것은 (말 하거나 할 것 같은) (1,eval)양보하는 표현 이지만 .eval(true && eval)(0 ? 0 : eval)eval

왜 신경 쓰나요?

Ecma 사양은 참조eval"직접 평가 호출"로 간주 하지만 단순히 eval간접 평가 호출이 되는 표현식 이며 간접 평가 호출은 전역 범위에서 실행되도록 보장됩니다.

내가 아직 모르는 것 :

  1. 직접 평가 호출 이 전역 범위에서 실행 되지 않는 상황은 무엇 입니까?
  2. 어떤 상황 this에서 전역 범위의 함수 가 전역 개체를 생성 하지 못할 수 있습니까?

여기에서 더 많은 정보를 얻을 수 있습니다 .

편집하다

내 첫 번째 질문에 대한 대답은 "거의 항상"입니다. 현재 범위 eval에서 직접 실행됩니다 . 다음 코드를 고려하십시오.

var x = 'outer';
(function() {
  var x = 'inner';
  eval('console.log("direct call: " + x)'); 
  (1,eval)('console.log("indirect call: " + x)'); 
})();

당연히 (heh-heh) 다음과 같이 출력됩니다.

direct call: inner
indirect call: outer

편집하다

더 많은 실험을 거친 후에 thisnull또는 로 설정할 수 없다고 잠정적으로 말할 것입니다 undefined. 다른 잘못된 값 (0, '', NaN, false)으로 설정할 수 있지만 매우 의도적으로 만 설정할 수 있습니다 .

나는 당신의 소스가 경미하고 가역적 인 두개-직장 반전으로 고통 받고 있으며 Haskell에서 일주일 동안 프로그래밍하는 것을 고려하고 싶을 것입니다.


조각,

var global = (function () {  
    return this || (1, eval)('this');  
}());  

엄격 모드에서도 전역 개체로 올바르게 평가됩니다. 엄격하지 않은 모드에서는의 값이 this전역 개체이지만 엄격 모드에서는입니다 undefined. 식은 (1, eval)('this')항상 전역 개체가됩니다. 그 이유는 간접적 구절에 대한 규칙을 포함합니다 eval. 에 대한 직접 호출 eval은 호출자의 범위 가지며 문자열 thisthis클로저 의 값으로 평가됩니다 . 간접 eval은 전역 범위의 함수 내에서 실행 된 것처럼 전역 범위에서 평가됩니다. 그 함수는 그 자체가 엄격 모드 함수가 아니기 때문에 전역 객체는 as로 전달되고 this표현식 'this'은 전역 객체로 평가됩니다. 이 표현 (1, eval)eval 간접적이어서 전역 객체를 반환합니다.

A1은 : (1, eval)('this')동일하지 않습니다 eval('this')때문에 간접 구절 직접 호출 주위에 특별한 규칙 eval.

A2 : 원본은 엄격 모드에서 작동하지만 수정 된 버전은 작동하지 않습니다.


Q1 :

JS에서 쉼표 연산자의 좋은 예라고 생각합니다. 이 기사에서 쉼표 연산자에 대한 설명이 마음에 듭니다 . http://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/

쉼표 연산자는 두 피연산자 (왼쪽에서 오른쪽으로)를 모두 평가하고 두 번째 피연산자의 값을 반환합니다.

Q2 :

(1, eval)('this')간접 평가 호출로 간주되며 ES5에서는 전역 적으로 코드를 실행합니다. 따라서 결과는 글로벌 컨텍스트가 될 것입니다.

http://perfectionkills.com/global-eval-what-are-the-options/#evaling_in_global_scope 참조


Q1: Multiple consecutive javascript statements separated by a comma take the value of the last statement. So:

(1, eval) takes the value of the last one which is a function reference to the eval() function. It apparently does it this way to make the eval() call into an indirect eval call that will be evaluated in the global scope in ES5. Details explained here.

Q2: There must be some environment that doesn't define a global this, but does define eval('this'). That's the only reason I can think of for that.

참고URL : https://stackoverflow.com/questions/9107240/1-evalthis-vs-evalthis-in-javascript

반응형