여기에서 여러분은 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
공간이 제한되어 있습니다. 더 많은 암시적 변환에 대해서는 내 기사를 참조하세요: From ++[[]][+[]]+[+[]]==10? JS
이렇게 말하면 핵심은 다 말씀드렸는데, 원저자가 이 글을 쓸 때 다른 분들과 상의를 해서 명확하게 설명하지 못한 부분이 많을 것 같아요. 코드에는 실제로 많은 지식 포인트가 포함되어 있습니다. 🎜
args는 배열이고 context.fn(args)에는 매개변수가 하나만 있습니다. 일반적인 상황에서는 Apply를 사용하여 배열을 매개변수로 변환할 수 있지만 여기서는 호출을 시뮬레이션하기 위해 Apply를 사용하는 것이 의미가 없습니다. 따라서 배열의 toString()을 사용하여 context 이외의 매개변수를 context.fn으로 이동합니다.
여기에서 여러분은
call
的原理,这里我简要还是说明一下原理,我也是参考JavaScript
권위 있는 가이드의 지침을 이해하고 이를 코드로 구현했다고 믿습니다.먼저 ECMAScript 사양의 중국어 버전에서
call
의 구문과 정의를 살펴보겠습니다.간단한 예를 들어보겠습니다:
으아악그런 다음
으아악call
를 사용한 후 출력을 살펴보세요.아래 질문에 밤을 기준으로 답변해 드리겠습니다.
먼저 위에서 시뮬레이션한 함수와 밤의 변수 간의 관계를 이해해야 합니다.
으아악이 단계에 주목하세요.
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 파싱 엔진을 사용하여 이 문자열 묶음의 내용을 파싱합니다. 이렇게 말하면
으아악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
공간이 제한되어 있습니다. 더 많은 암시적 변환에 대해서는 내 기사를 참조하세요: From ++[[]][+[]]+[+[]]==10? JS
이렇게 말하면 핵심은 다 말씀드렸는데, 원저자가 이 글을 쓸 때 다른 분들과 상의를 해서 명확하게 설명하지 못한 부분이 많을 것 같아요. 코드에는 실제로 많은 지식 포인트가 포함되어 있습니다. 🎜
args는 배열이고
context.fn(args)
에는 매개변수가 하나만 있습니다. 일반적인 상황에서는 Apply를 사용하여 배열을 매개변수로 변환할 수 있지만 여기서는 호출을 시뮬레이션하기 위해 Apply를 사용하는 것이 의미가 없습니다. 따라서 배열의 toString()을 사용하여 context 이외의 매개변수를 context.fn으로 이동합니다.인수[0]은 context이기 때문이죠
루프 변수가 1부터 시작하는 거 못 보셨나요?