>  Q&A  >  본문

javascript - js에서 호출 메소드 구현

으아악

호출 구현을 시뮬레이션하기 위한 것입니다. 왜 문자열을 푸시하고 다음에 eval을 사용해야 합니까? 인수[i]를 직접 전달한 다음 context.fn(args)를 사용하면 어떨까요?

PHP中文网PHP中文网2685일 전822

모든 응답(3)나는 대답할 것이다

  • 给我你的怀抱

    给我你的怀抱2017-06-12 09:32:07

    여기에서 여러분은 call的原理,这里我简要还是说明一下原理,我也是参考JavaScript권위 있는 가이드의 지침을 이해하고 이를 코드로 구현했다고 믿습니다.

    먼저 ECMAScript 사양의 중국어 버전에서 call의 구문과 정의를 살펴보겠습니다.

    간단한 예를 들어보겠습니다:

    으아악

    그런 다음 call를 사용한 후 출력을 살펴보세요.

    으아악

    아래 질문에 밤을 기준으로 답변해 드리겠습니다.

    call的实现,请问为什么要push一个字符串,下面再用eval?直接传入arguments[i],然后下面用context.fn(args) 구현을 시뮬레이션하는 것입니다. 왜 문자열을 푸시하고 다음으로 eval을 사용해야 합니까? arguments[i]를 직접 전달한 다음 context.fn(args)를 사용하면 안 될까요?

    먼저 위에서 시뮬레이션한 함수와 밤의 변수 간의 관계를 이해해야 합니다.

    으아악

    이 단계에 주목하세요. jawil.sayHello的引用地址给了lulin.sayHello

    그런데 jawil.sayHello.call(context,arg1,arg2,arg3,arg4)

    마음대로 골라보세요context得到args=[arg1,arg2,arg3,arg4]

    그럼 실행lulin.sayHello([arg1,arg2,arg3,arg4])ㅋㅋㅋ아주 헷갈리죠? 괜찮아 보이는데 실제로는 4개의 매개변수가 있었는데, 이제 그것들이 하나의 배열로 합쳐져서 하나의 배열 매개변수가 되었습니다. 여기에 문제가 있습니다.

    그렇다면 이 문제를 어떻게 해결할 수 있을까요? 아이디어는 위와 같으며, 모든 매개변수를 문자열에 넣은 다음 eval를 사용하여 실행합니다.

    우리가 원하는 효과는 lulin.sayHello(arg1,arg2,arg3,arg4)입니다. lulin.sayHello가 매개변수를 재구성해야 하기 때문에 매개변수를 lulin.sayHello(arg1,arg2,arg3,arg4)这样的,因为lulin.sayHello要重组参数,你不能拿到一个参数执行一次函数吧,或者把参数存到一起一次执行吧,唯一的想到的做法就是把所有参数拼成字符串,然后用eval얻을 수 없습니다. 매개변수

    로 함수를 한 번 실행하거나,

    매개변수를 함께 저장하고 한 번 실행lulin.sayHello([arg1,arg2,arg3,arg4]),也不是lulin.sayHello(arg1),lulin.sayHello(arg2) 생각나는 유일한 방법은 모든 매개변수를 문자열에 넣은 다음

    를 사용하여 실행하는 것입니다.

    이와 유사합니다: "lulin.sayHello(arg1,arg2,arg3,arg4)" 이것은 우리가 원하는 방식입니다.

    도 아니고 lulin.sayHello(arg1),lulin.sayHello도 아닙니다. (arg2)...

    eval평가란 무엇인가요? 여기서는 아무것도 모르는 척하겠습니다.

    기능

    정의와 사용법

    을 간단히 살펴보겠습니다.

    eval() 함수는 문자열을 계산하고 그 안의 JavaScript 코드를 실행할 수 있습니다.
    eval(string)

    문법:

    🎜🎜문자열이 필요합니다. 평가할 JavaScript 표현식 또는 실행할 명령문이 포함된 평가할 문자열입니다. 이 메소드는 원시 문자열만 매개변수로 허용합니다. 문자열 매개변수가 원시 문자열이 아닌 경우 메소드는 변경되지 않은 상태로 반환됩니다. 따라서 String 객체를 eval() 함수에 대한 인수로 전달하지 마십시오. 🎜

    간단히 말하면 JavaScript 파싱 엔진을 사용하여 이 문자열 묶음의 내용을 파싱합니다. 이렇게 말하면 eval看成是<script> 태그를 넣으면 이렇게 이해할 수 있습니다.

    으아악

    이것과 같습니다

    으아악

    자, 위의 코드를 다시 살펴보겠습니다. 사실 여전히 함정이 있습니다. 모달의 직관적인 관점을 살펴보겠습니다. 다음은 전체 디버깅 코드입니다.

    으아악

    args의 출력을 살펴보세요:

    ["인수[1]", "인수[2]"]

    그런 다음 'context.fn(' + args + ')'의 출력을 살펴보세요.

    "context.fn(arguments[1],arguments[2])"좀 헷갈리지 않나요

    실제로 여기에는 암시적 변환이 포함됩니다.

    'jawil'+[1,2]+[3,4]+3는 무엇과 같나요? 'jawil'+[1,2]+[3,4]+3等于多少?
    等于"jawil1,23,43"
    其实这个相当于'jawil'+[1,2].toString()+[3,4].toString()+3"jawil1,23,43"과 동일

    실제로 이는 'jawil'+[1,2].toString()+[3,4].toString( )+3< /code>

    공간이 제한되어 있습니다. 더 많은 암시적 변환에 대해서는 내 기사를 참조하세요: From ++[[]][+[]]+[+[]]==10? JS

    이렇게 말하면 핵심은 다 말씀드렸는데, 원저자가 이 글을 쓸 때 다른 분들과 상의를 해서 명확하게 설명하지 못한 부분이 많을 것 같아요. 코드에는 실제로 많은 지식 포인트가 포함되어 있습니다. 🎜

    회신하다
    0
  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-06-12 09:32:07

    args는 배열이고 context.fn(args)에는 매개변수가 하나만 있습니다. 일반적인 상황에서는 Apply를 사용하여 배열을 매개변수로 변환할 수 있지만 여기서는 호출을 시뮬레이션하기 위해 Apply를 사용하는 것이 의미가 없습니다. 따라서 배열의 toString()을 사용하여 context 이외의 매개변수를 context.fn으로 이동합니다.

    회신하다
    0
  • 淡淡烟草味

    淡淡烟草味2017-06-12 09:32:07

    인수[0]은 context이기 때문이죠
    루프 변수가 1부터 시작하는 거 못 보셨나요?

    회신하다
    0
  • 취소회신하다