JavaScript 의 함수 호출 을 깊이 학습 합 니 다.
많은 사람들 이 자바 스 크 립 트 를 공부 하 는 과정 에서 함수 매개 변수 전달 방식 에 현혹 되 었 을 수도 있 습 니 다.깊 은 정신 에 따라 저 는 소스 코드 에서 답 을 찾 고 싶 습 니 다.그러나 이 일 을 하기 전에 먼저 몇 가지 개념 을 명 확 히 하고 싶 습 니 다.값 전달,인용 전달 등 고유 한 명칭 을 버 리 고 영어 로 돌아 갑 니 다.
call by reference && call by value && call by sharing
각각 우리 가 이해 하 는 C++의 인용 전달,값 전달 이다.세 번 째 는 비교적 혼 란 스 럽 습 니 다.공식 해석 은 receives the copy of the reference to object 입 니 다.나 는 통속 적 인 말로 설명 했다.
Object 는 key 의 집합 으로 이해 할 수 있 습 니 다.Object 가 key 가 가리 키 는 데 이 터 는 인용 성질 입 니 다.(여기 서 포인터 가 실현 되 는 지,C+인용 이 실현 되 는 지 깊이 따 지지 않 습 니 다)함수 가 받 은 것 은 변수의 copy 입 니 다.변 수 는 Object 의 인용 을 포함 하고 하나의 값 전달 입 니 다.
그러면 분명 합 니 다.함수 가 인삼 을 전달 할 때 우리 가 받 은 대상 형 인삼 은 실제 인삼 의 복사 이기 때문에 형 인삼 의 방향 을 직접 바 꾸 는 것 은 불가능 합 니 다.Object 자체 의 key 가 모두 인용 되 어 있 기 때문에 key 의 지향 점 을 수정 하 는 것 이 가능 합 니 다.
증명 하 다.
간단하게 몇 단락 의 코드 를 넣 으 면 바로 증명 할 수 있다
Code 1:함수 가 key 가 가리 키 는 데 이 터 를 수정 할 수 있 습 니 다.
let func = obj => { obj.name = 'Dosk' };
let obj = {name : 'Alxw'};
console.log(obj); //{ name: 'Alxw' }
func(obj)
console.log(obj); //{ name: 'Dosk' }
Code 2:함 수 는 obj 를 수정 할 수 없습니다.
let func = obj => { obj = {} };
let obj = {name : 'Alxw'};
console.log(obj); //{ name: 'Alxw' }
func(obj)
console.log(obj); //{ name: 'Alxw' }
Code 3:내부 obj 와 외부==결과 가 같 음
let def = {name : 'Alxw'};
let func = obj => { console.log(obj === def) };
func(def); //true
그래서 세 번 째 코드 에 의문 이 있 을 수 있 습 니 다.obj 가 def 의 복사 인 이상 왜==조작 이 진실 일 수 있 습 니까?====작업 이 Object 에 대한 비교 가 메모리 에 있 는 주소 라 고 하지 않 았 습 니까?복사 라면 false 여야 합 니까?그래서 우 리 는 구 글 V8 의 소스 코드 로 돌아 가 이 일 을 보 았 다.
Google V8 깊이 들 어가 기
원본 코드 의 엄격 함 은 조작 코드 부분 과 같다.
bool Object::StrictEquals(Object* that) {
if (this->IsNumber()) {
if (!that->IsNumber()) return false;
return NumberEquals(this, that);
} else if (this->IsString()) {
if (!that->IsString()) return false;
return String::cast(this)->Equals(String::cast(that));
} else if (this->IsSimd128Value()) {
if (!that->IsSimd128Value()) return false;
return Simd128Value::cast(this)->Equals(Simd128Value::cast(that));
}
return this == that;
}
마지막 상황 으로 보 입 니 다.이론 적 으로 def 와 obj 가 다른 대상 이 라면 false 로 돌아 가 야 합 니 다.이것 은 앞에서 말 한 것 을 뒤 집 는 것 이 아 닙 니까?사실 Google V8 내부 에서 Object 를 실례 화 할 때 그 자체 가 동적 실례 화 라 는 것 을 간과 하지 않 았 습 니 다.컴 파일 형 언어 에 서 는 동적 실례 화가 메모리 에 만 있 을 수 있 고 포인터 만 참조 할 수 있다 는 것 을 알 고 있 습 니 다.이 결론 은 Local,Handle 등 class 의 실현 과 관련 이 있다 는 것 을 증명 하 는 것 입 니 다.저 는 너무 번 거 롭 고 간단 한 증명 방식 이 있 습 니 다.즉,소스 코드 를 검색 하여 모든 호출Object::StrictEquals
을 받 은 곳 은 주 소 를 찾 지 않 고 직접 들 어 옵 니 다.그러나 값 전달 변수 가 Object 의 인용 을 포함 하 는 만큼 이론 적 으로 도 Object 를 수정 할 수 있어 야 하 는데 왜 세 번 째 코드 는 수정 할 수 없 느 냐 는 질문 이 나 올 것 이다.
간단 한 이 치 는 JavaScript 언어 논리 차원 에서 의 조작 이란 Google V8 의 인 스 턴 스 를 호출 하 는 방법 일 뿐 이 정도 까지 는 작 동 할 수 없습니다(물론 잠재 적 인 BUG 는 아 닙 니 다-).
다시 정의
나 는 여기까지 콜 비 쉐 어 링 에 게 다시 한 번 설명 할 수 있 을 것 이 라 고 생각한다.
확실히 전달 할 때 값 전달 이지 만 내용 은 Object 의 지침 을 포함 하고 이 지침 을 수정 할 수 없습니다.그 는 여러 변수 가 공유 합 니 다.
또 다른 간단 한 증명
자,소스 코드 보 자.
V8_DEPRECATE_SOON("Use maybe version",
Local<Value> Call(Local<Value> recv, int argc,
Local<Value> argv[]));
V8_WARN_UNUSED_RESULT MaybeLocal<Value> Call(Local<Context> context,
Local<Value> recv, int argc,
Local<Value> argv[]);
위 에 있 는 것 은 곧 버 려 질 인터페이스 입 니 다.공교롭게도 제 가 본 이 버 전 코드 는 버 려 질 코드 를 많이 포함 하고 있 습 니 다.보시 면 됩 니 다.중점 은 두 번 째 인터페이스 로 함수 의 유일한 호출 인터페이스 이다.안에 있 는Local<Value>
은 최종 적 으로 C++의 비트 복 제 를 호출 하기 때문에 값 전달 임 을 간단하게 증명 할 수 있다.이 가능 하 다,~할 수 있다,...
잊 지 마 세 요.우리 가 정의 하 는 변 수 는 모두 비슷 한
Handle<Object>
형식 입 니 다.그래서 그들 사이 의 대상 이 공유 하 는 것 입 니 다.우리 가 말 하 는 자바 스 크 립 트 에서 변 수 는 Object 의 인 스 턴 스 를 직접적 으로 가리 키 지 않 습 니 다!!마지막 마지막
한 마디 로 이해 하기 힘 들 고 틀 릴 수도 있 지만 자 바스 크 립 트 언어 차원 에서 특성 을 확인 하 는 것 이 중요 하 다.
위 에서 말 한 것 은 소 편 이 여러분 에 게 소개 한 자 바스 크 립 트 의 함수 호출 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.