호출 구현을 시뮬레이션하기 위한 것입니다. 왜 문자열을 푸시하고 다음에 eval을 사용해야 합니까? 인수[i]를 직접 전달한 다음 context.fn(args)를 사용하면 어떨까요?
给我你的怀抱2017-06-12 09:32:07
여기에서 여러분은 call
的原理,这里我简要还是说明一下原理,我也是参考JavaScript
권위 있는 가이드의 지침을 이해하고 이를 코드로 구현했다고 믿습니다.
먼저 ECMAScript 사양의 중국어 버전에서 call
의 구문과 정의를 살펴보겠습니다.
간단한 예를 들어보겠습니다:
으아악그런 다음 call
를 사용한 후 출력을 살펴보세요.
아래 질문에 밤을 기준으로 답변해 드리겠습니다.
은
call
的实现,请问为什么要push一个字符串,下面再用eva
l?直接传入arguments[i]
,然后下面用context.fn(args)
구현을 시뮬레이션하는 것입니다. 왜 문자열을 푸시하고 다음으로eva
l을 사용해야 합니까?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으로 이동합니다.