js:this 지향 문제

5532 단어

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가 등장하는 장면을 네 가지로 나눈다. 간단하게 말하면 다음과 같다.
  • 대상이 있으면 호출 대상을 가리킨다
  • 호출 대상이 없으면 전역 대상을 가리킨다
  • new구조로 새로운 대상을 가리킨다
  • apply나call 또는bind를 통해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에서 구조 함수, 일반 함수, 대상 방법, 패키지 등 네 가지는 명확한 경계선이 없다.경계선은 모두 사람의 마음속에 있다.
  • apply와call 호출 및bind 귀속: 귀속된 대상을 가리킨다
  • apply () 방법은 두 개의 매개 변수를 받아들인다. 첫 번째는 함수 운행의 작용역이고, 다른 하나는 하나의 매개 변수 그룹(arguments)이다.
    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

    좋은 웹페이지 즐겨찾기