js:this 지향 문제
var 역할 영역
먼저 간단한 예를 살펴보자.
source-js
var parent = function () {
var name = "parent_name";
var age = 13;
var child = function () {
var name = "child_name";
var childAge = 0.3;
// => child_name 13 0.3
console.log(name, age, childAge);
};
child();
// will throw Error
// ReferenceError: childAge is not defined
console.log(name, age, childAge);
};
parent();
직감적으로 내부 함수는 외부 함수의 변수에 접근할 수 있고 외부는 내부 함수의 변수에 접근할 수 없다.위의 예에서 내부 수child는 변수age에 접근할 수 있지만, 외부 함수parent는child의 변수childAge에 접근할 수 없기 때문에 정의되지 않은 변수의 이상을 던집니다.
중요한 일이 있습니다. var을 잊어버리면 변수는 전역 변수로 성명됩니다.
function foo() {
value = "hello";
}
foo();
console.log(value); // hello
console.log(global.value) // hello
이 예는 정상적인 출력
hello
을 할 수 있는데 value
변수가 정의할 때 var
키워드를 사용하지 않았기 때문에 전역 변수로 정의되었다.Node에서 전역 변수는 global
객체 아래에 정의됩니다.브라우저에서 전역 변수는 window
객체 아래에 정의됩니다.전역 변수를 정의하려면 global
또는 window
대상에 표시합니다.전역 변수를 잘못 정의한 문제는 jshint에서 검출할 수 있습니다. 만약sublime 편집기를 사용한다면 SublimeLinter
플러그인을 설치하십시오. 이것은 플러그인이 다중 언어의 문법 오류 검출을 지원하고 js의 검출은 원생 지원입니다.JavaScript에서 변수의 로컬 역할 영역은 함수 수준입니다.C 언어와 달리 C 언어에서는 역할 영역이 블록 수준입니다.JavaScript에는 블록 레벨 도메인이 없습니다.js에서 함수에 설명된 변수는 전체 함수에 정의되어 있습니다.예를 들어 다음과 같은 코드 세그먼트, 변수 i와value는 for 순환 코드 블록에 정의되어 있지만 코드 블록 밖에서는 i와value에 접근할 수 있습니다.function foo() {
for (var i = 0; i < 10; i++) {
var value = "hello world";
}
console.log(i); // 10
console.log(value);// hello world
}
foo();
그래서 함수에 필요한 변수를 미리 설명해야 한다는 말이 있다. 즉, 함수체의 맨 위에서 사용할 수 있는 양을 설명하면 기괴한 버그가 발생하는 것을 피할 수 있다.그러나 나는 개인적으로 이 점을 준수하는 것을 좋아하지 않는다. 일반적으로 모두 현용으로 성명하는 것이다.이런 잘못된 검사는 jshint에 맡기면 됩니다.
가방을 닫다
폐쇄라는 개념은 함수식 프로그래밍에서 흔히 볼 수 있는데 간단하게 말하면 내부 함수가 외부 함수에 정의된 변수에 접근할 수 있도록 하는 것이다.만약 우리가 일련의 함수를 실현하려면:add10,add20, 그것들의 정의는
int add10(int n)
이다.이를 위해 다음과 같이 adder라는 구조기를 구축했습니다.var adder = function (x) {
var base = x;
return function (n) {
return n + base;
};
};
var add10 = adder(10);
console.log(add10(5));
var add20 = adder(20);
console.log(add20(5));
adder를 호출할 때마다adder는 우리에게 함수를 되돌려줍니다.우리가adder에 전송한 값은base라는 변수에 저장됩니다.되돌아오는 함수가 베이스의 값을 인용했기 때문에base의 인용 계수는 +1입니다.반환 함수가 쓰레기로 회수되지 않을 때base도 계속 존재합니다.나는 잠시 어떤 실용적인 예도 생각해 내지 못했는데, 만약 이 부분을 깊이 이해하고 싶다면, 이 편을 좀 볼 수 있다
http://coolshell.cn/articles/6731.html
닫힌 구덩이
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 5);
}
위의 이 코드 블록은 다섯 개
5
를 출력할 것이며, 우리가 예상한 결과는 0 1234를 출력하는 것이다.이렇게 된 이유는 set Timeout의 i가 외부 i의 인용이기 때문이다.setTimeout 코드가 해석될 때, 실행할 때 값이 아니라 i의 인용만 기록됩니다.한편, set Timeout이 촉발되었을 때 다섯 개의 set Timeout 중의 i는 동시에 값을 얻는다. 그들은 모두 바깥쪽의 같은 i를 가리키고, 그 i의 값은 교체가 끝날 때 5이기 때문에 다섯 번 인쇄했다5
.우리가 예상한 결과를 얻기 위해 우리는 i를 국부적인 변수로 부여하여 외부 교체의 영향을 벗어날 수 있다.for (var i = 0; i < 5; i++) {
(function (idx) {
setTimeout(function () {
console.log(idx);
}, 5);
})(i);
}
this
함수가 실행될 때,this는 항상 이 함수를 호출하는 대상을 가리킨다.this의 지향을 판단하려면 사실은this가 있는 함수가 누구에 속하는지 판단하는 것이다.이 책에서this가 등장하는 장면을 네 가지로 나눈다. 간단하게 말하면 다음과 같다.
1) 함수가 속한 대상이 있을 때: 소속 대상 함수가 속한 대상을 가리킬 때, 통상적으로
.
표현식을 통해 호출되며, 이때 this
자연적으로 소속 대상을 가리킨다.예:var myObject = {value: 100};
myObject.getValue = function () {
console.log(this.value); // 100
// { value: 100, getValue: [Function] },
// myObject
console.log(this);
return this.value;
};
console.log(myObject.getValue()); // => 100
getValue()
는 대상myObject
에 속하고 myOjbect
에서 호출되기 때문에 .
는 대상this
을 가리킨다.var myObject = {value: 100};
myObject.getValue = function () {
var foo = function () {
console.log(this.value) // => undefined
console.log(this);// global
};
foo();
return this.value;
};
console.log(myObject.getValue()); // => 100
상기 코드 블록에서
myObject
함수는 foo
함수 안에 정의되어 있지만 실제로는 getValue
에 속하지도 않고 getValue
에 속하지도 않는다.myObject
는 어떠한 대상에 귀속되지 않았기 때문에 호출할 때 foo
바늘이 전체 대상this
을 가리킨다.듣자니 이것은 설계 오류라고 한다.3) 구조기의this: 새로운 대상을 가리킨다
js에서 우리는
global
키워드를 통해 구조 함수를 호출합니다. 이때this는 이 새로운 대상에 귀속됩니다.var SomeClass = function(){
this.value = 100;
}
var myCreate = new SomeClass();
console.log(myCreate.value); // 100
참고로 js에서 구조 함수, 일반 함수, 대상 방법, 패키지 등 네 가지는 명확한 경계선이 없다.경계선은 모두 사람의 마음속에 있다.
call () 방법의 첫 번째 매개 변수의 의미는 apply () 방법과 같지만 다른 매개 변수는 하나하나 열거해야 합니다.
간단하게 말하자면,call의 방식은 우리가 평소에 호출하는 함수에 더욱 가깝고, apply는 우리가array 형식의 수조를 그것에게 전달해야 한다.그것들은 서로 전환할 수 있다.
var myObject = {value: 100};
var foo = function(){
console.log(this);
};
foo(); // global
foo.apply(myObject); // { value: 100 }
foo.call(myObject); // { value: 100 }
var newFoo = foo.bind(myObject);
newFoo(); // { value: 100 }
본고는 에서 전한다 ---Lesson 11
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.