programing

{} + {}이(가) 클라이언트 측에만 NaN이 있는 이유는 무엇입니까?왜 Node.js에 없습니까?

lastcode 2023. 8. 10. 18:51
반응형

{} + {}이(가) 클라이언트 측에만 NaN이 있는 이유는 무엇입니까?왜 Node.js에 없습니까?

하는 동안에[] + []빈 문자열입니다.[] + {}이라"[object Object]",그리고.{} + []이라0이유는{} + {}NaN?

> {} + {}
  NaN

제 질문은 왜가 아닙니다.({} + {}).toString()이라"[object Object][object Object]"하는 동안에NaN.toString()이라"NaN"이 부분은 이미 여기에 답이 있습니다.

제 질문은 왜 이런 일이 클라이언트 쪽에서만 일어나는가 하는 것입니다.서버 측(Node.js){} + {}이라"[object Object][object Object]".

> {} + {}
'[object Object][object Object]'

요약:

클라이언트 측:

 [] + []              // Returns ""
 [] + {}              // Returns "[object Object]"
 {} + []              // Returns 0
 {} + {}              // Returns NaN

 NaN.toString()       // Returns "NaN"
 ({} + {}).toString() // Returns "[object Object][object Object]"
 var a = {} + {};     // 'a' will be "[object Object][object Object]"

Node.js에서:

 [] + []   // Returns "" (like on the client)
 [] + {}   // Returns "[object Object]" (like on the client)
 {} + []   // Returns "[object Object]" (not like on the client)
 {} + {}   // Returns "[object Object][object Object]" (not like on the client)

업데이트된 참고 사항: 이 문제는 Chrome 49에서 해결되었습니다.

매우 흥미로운 질문입니다!공부합시다.

근본 원인

차이의 근원은 Node.js가 이러한 문을 평가하는 방식과Chrome 개발 도구의 작동 방식.

Node.js의 기능

Node.js는 이에 대해 repl 모듈을 사용합니다.

Node.js REPL 소스 코드에서 다음을 수행합니다.

self.eval(
    '(' + evalCmd + ')',
    self.context,
    'repl',
    function (e, ret) {
        if (e && !isSyntaxError(e))
            return finish(e);
        if (typeof ret === 'function' && /^[\r\n\s]*function/.test(evalCmd) || e) {
            // Now as statement without parens.
            self.eval(evalCmd, self.context, 'repl', finish);
        }
        else {
            finish(null, ret);
        }
    }
);

이것은 마치 달리는 것처럼 행동합니다.({}+{})Chrome 개발자 도구에서, 또한 생산합니다."[object Object][object Object]"예상하신 대로

크롬 개발자 도구의 역할

반면에 Chrome 개발자 도구는 다음을 수행합니다.

try {
    if (injectCommandLineAPI && inspectedWindow.console) {
        inspectedWindow.console._commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
        expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}";
    }
    var result = evalFunction.call(object, expression);
    if (objectGroup === "console")
        this._lastResult = result;
    return result;
}
finally {
    if (injectCommandLineAPI && inspectedWindow.console)
        delete inspectedWindow.console._commandLineAPI;
}

그래서 기본적으로, 그것은 다음을 수행합니다.call라는 표현을 가진 물체에.식은 다음과 같습니다.

with ((window && window.console && window.console._commandLineAPI) || {}) {
    {}+{};// <-- This is your code
}

따라서, 보시는 것처럼, 식은 괄호를 사용하지 않고 직접 평가됩니다.

Node.js가 다르게 작동하는 이유

Node.js의 소스는 이를 정당화합니다.

// This catches '{a : 1}' properly.

노드가 항상 이렇게 작동하지는 않았습니다.다음은 이를 변경한 실제 커밋입니다.Ryan은 변경 사항에 대해 다음과 같은 의견을 남겼습니다. "REPL 명령이 평가되는 방식을 개선하십시오."라는 차이점을 예로 들 수 있습니다.


코뿔소

업데이트 - OP는 Rhino가 어떻게 동작하는지(그리고 왜 그것이 Chrome dev tools처럼 동작하는지, nodejs와는 다르게 동작하는지)에 관심이 있었습니다.

Rhino는 V8을 사용하는 Chrome 개발자 도구와 Node.js의 REPL과는 전혀 다른 JS 엔진을 사용합니다.

다음은 Rhino 셸에서 Rhino를 사용하여 JavaScript 명령을 평가할 때 발생하는 기본 파이프라인입니다.

  • 껍질이 달립니다.

  • 차례로, 이렇게 부릅니다. new IProxy(IProxy.EVAL_INLINE_SCRIPT);예를 들어 코드가 인라인 스위치 -e로 직접 전달된 경우.

  • 이것은 IProxy의 메소드에 해당합니다.

  • (src)를 호출합니다.이것은 단순히 문자열을 컴파일하고 평가합니다.

기본적으로:

Script script = cx.compileString(scriptText, "<command>", 1, null);
if (script != null) {
    script.exec(cx, getShellScope()); // <- just an eval
}

세 개 중에서, 코뿔소의 등껍질은 실제와 가장 가까운 것입니다.eval꾸러미도 없이코뿔소의 것이 실제와 가장 가깝습니다.eval()진술 그리고 당신은 그것이 정확히 처럼 행동하기를 기대할 수 있습니다.eval그럴 것이다.

언급URL : https://stackoverflow.com/questions/17268468/why-is-nan-only-on-the-client-side-why-not-in-node-js

반응형