제4 장 함수

9676 단어
함수.
JS 가 가장 잘 설계 한 것 은 바로 그것 의 함수 의 실현 이다.그것 은 거의 완벽 에 가깝다.하지만 JS 함수 에 도 하 자가 있 을 것 이 라 고 예상 할 수 있 을 것 이다.프로 그래 밍 이란 한 그룹의 수 요 를 한 그룹의 함수 와 데이터 구조 로 분해 하 는 기능 이다.
1. 함수 개체
각 함수 가 생 성 될 때 두 개의 숨겨 진 속성 을 추가 합 니 다. 함수 의 문맥 과 함수 행 위 를 실현 하 는 코드 입 니 다.함수 의 남 다른 점 은 호출 될 수 있다 는 것 이다.
2. 편지 숫자 면 량
3. 호출
함수 하 나 를 호출 하면 현재 함수 의 실행 을 중단 하고 제어 권 과 파 라 메 터 를 새 함수 에 전달 합 니 다.
JS 에는 모두 4 가지 호출 모델 이 있 습 니 다. 방법 호출 모델, 함수 호출 모델, 구조 기 호출 모델, apply 호출 모델 이 있 습 니 다. 이런 모델 들 은 관건 적 인 매개 변 수 를 어떻게 초기 화 하 는 지 this 에 차이 가 있 습 니 다.
4. 방법 호출 모드
함수 가 대상 의 속성 으로 저 장 될 때, 우 리 는 그것 을 하나의 방법 이 라 고 부른다.하나의 방법 이 호출 되 었 을 때, this 는 이 대상 에 귀속 되 었 다.
var myObject = {
    value: 0,
    increment: function( inc ){
         this.value += typeof inc === 'number' ? inc : 1;
    }
}

myObject.increment();
myObject.value ==> 1

myObject.increment(2);
myObject.value ==> 2

5. 함수 호출 모드
함수 가 대상 의 속성 이 아 닐 때 함수 로 호출 됩 니 다.
var add = function(a, b){
    return a + b;
}
var sum = add(3, 4);

이 모드 에서 함 수 를 호출 할 때 this 는 전역 대상 에 연결 되 어 있 습 니 다.이것 은 언어 설계 상의 잘못 이다!!!만약 언어 디자인 이 정확 하 다 면 내부 함수 가 호출 될 때 this 는 외부 함수 의 this 변수 에 연결 되 어야 합 니 다.이 디자인 오류 의 결 과 는 방법 이 내부 함 수 를 이용 하여 작업 을 도 울 수 없다 는 것 입 니 다. 내부 함수 의 this 가 잘못된 값 으로 연결 되 어 있 기 때문에 이 방법 이 대상 에 대한 접근 권 을 공유 할 수 없습니다!
var add  = function(a,b){
  console.log(this)      //   this  window  !!!
}

var obj = {
    age: 21,
    value: 2,
    double: function(){
        var helper = function(){
            this.value = this.age;
            console.log(this)
        }
        helper()
    }
}
console.log(obj.double())  ==> undefined;

//  
var obj = {
    age: 21,
    value: 2,
    double: function(){
        function helper(){
            this.value = this.age;
            console.log(this)
        }
        helper()
    }
}
console.log(obj.double())  ==> undefined;

undefined 를 얻 은 이유: 함수 호출 모드 로 함 수 를 호출 할 때 this 는 전체 대상 에 연결 되 었 습 니 다. helper 내부 의 this 는 window 입 니 다. 이전에 저 는 helper 내부 의 this 가 내부 역할 영역 이 라 고 생각 했 기 때문에 this 는 그 내 부 를 대표 할 수 있 을 뿐 부모 요 소 를 방문 할 수 없습니다. 오늘 에 야 이것 이 전체 변수 라 는 것 을 알 게 되 었 습 니 다!!
해결 방법:
var obj = {
    age: 21,
    value: 2,
    double: function(){
        var that = this;
        var helper = function(){
            that.value = that.age;
            console.log(that.value)
        }
        helper()
    }
}
console.log(obj.double())  ==> 21;

6. 구조 기 호출 모드
JS 는 원형 계승 에 기반 한 언어 다.이것 은 대상 이 다른 대상 으로 부터 직접 속성 을 계승 할 수 있다 는 것 을 의미한다.이 언어 는 유형 이 없다.함수 앞에서 new 를 가 져 와 호출 하면 뒤에서 이 함수 에 연 결 된 prototype 구성원 의 새로운 대상 을 만 들 고 this 는 그 새 대상 에 연 결 됩 니 다.
코드 예:
//  ,    ,               
var Quo = function(string){
    this.status = string;
}

//  Quo           get_status     
Quo.prototype.get_status = function() {
    return this.status;
}

//     Quo   
var myQuo = new Quo('confused');

myQuo.get_status() ==> confused;

하나의 함수 가 생 성 된 목적 이 new 접두사 와 결합 하여 호출 하 기 를 원한 다 면 구조 함수 라 고 합 니 다.
나 는 이런 형식의 구조 함 수 를 사용 하 는 것 을 추천 하지 않 는 다.다음 장 에서 우 리 는 더 좋 은 대체 방식 을 볼 수 있 을 것 이다. (라 는 책의 큰 특징 은 한 가지 말 을 다 한 후에 이것 은 우리 가 사용 하 는 것 을 건의 하지 않 는 다 는 것 이다. 더 좋 은 대체 방식 을 보 려 면 다음 장 을 보 세 요. 정말 다음 장 을 공부 하 라 고 강요 하 는 것 이다!!)
7. 호출 모드 적용
apply 방법 은 호출 함수 에 매개 변수 배열 을 구축 하고 this 의 값 을 선택 할 수 있 도록 합 니 다.apply 방법 은 두 개의 인 자 를 받 습 니 다. 첫 번 째 는 this 에 연결 할 값 이 고 두 번 째 는 매개 변수 배열 입 니 다.
var add = function(a, b) {
    return a + b;
}

/ / 두 개의 숫자 를 포함 하 는 배열 을 만 들 고 이 를 더 합 니 다.
var array = [3,4];
var sum = add.apply(null, array)   // sum  7

매개 변수
함수 가 호출 될 때 '무료' 배 송 의 인 자 를 얻 을 수 있 습 니 다. 바로 arguments 배열 입 니 다.함 수 는 이 매개 변 수 를 통 해 호출 되 었 을 때 전달 되 는 매개 변수 목록 에 접근 할 수 있 습 니 다. 함수 성명 에 할당 되 지 않 았 을 때 정의 되 지 않 은 형식 매개 변수의 불필요 한 매개 변 수 를 포함 합 니 다.
var sum = function(){
    var i, sum = 0;
    for(i = 0; i < arguments.length; i++){
        sum += arguments[i];
    }
    return sum;
}
sum(4,8,15,16,23,42) ==> 108

언어의 디자인 오류 로 인해 arguments 는 진정한 배열 이 아 닙 니 다.이것 은 '유사 한 배열' 의 대상 일 뿐 arguments 는 length 속성 을 가지 고 있 지만 배열 의 방법 이 없습니다.
1. 복귀
return 문 구 는 함 수 를 미리 되 돌려 주 는 데 사용 할 수 있 습 니 다. return 이 실 행 될 때 함 수 는 남 은 문 구 를 실행 하지 않 고 바로 돌아 갑 니 다.함수 가 반환 값 을 지정 하지 않 으 면 undefined 로 돌아 갑 니 다.
var Vue = function(a){
   return this
}
Vue.prototype.returnThis = function(){
   return this;
}
var vue = new Vue();
vue.returnThis() ==》 Vue{}

2. 이상
(1) throw
var add = function(a, b){
   if( typeof a !== 'number' || typeof b !== 'number' ){
       throw {
           name: 'TypeError',
           message: 'add needs numbers'
       };
   }
   return a + b;
}

add(3,'ww') ==> { name: 'TypeError', message: 'add needs numbers' }

(2) try 문장의 catch 종문
var try_it = function(){
    try {
        add('seven');
    } catch(e) {
        document.writenIn(e.name + ':' + e.message);
    }
}
try_it();

하나의 try 문 구 는 모든 이상 한 catch 코드 블록 을 캡 처 할 수 있 습 니 다.
3. 유형의 기능 확장
기본 유형 에 추가 하 는 방법 을 통 해우 리 는 언어의 표 현 력 을 크게 향상 시 킬 수 있다.
Number 원형 에 숫자 중의 정수 부분 을 추출 하 는 방법 을 추가 합 니 다.
Number.method('integer', function(){
    return Math[this < 0 ? 'ceil' : 'floor'](this);
})

(-10/3).integer();

String 프로 토 타 입 에 문자열 의 앞 뒤 공백 을 제거 하 는 방법 을 추가 합 니 다.
String.method('trim', function(){
    return this.replace(/^\s+|\s+$/g, '');
})

기본 유형 에 방법 을 추가 함으로써 우 리 는 언어 표 현 력 을 크게 향상 시 킬 수 있다.사실 이 점 에 대해 저 는 개인 적 으로 Jquery, underscore 등 라 이브 러 리 를 사용 하여 각종 기본 유형 과 인용 유형의 처 리 를 실현 하 는 것 을 권장 합 니 다.원형 체인 에 너무 많은 방법 을 추가 하면 구조 가 혼 란 스 럽 고 코드 가 유지 되 지 않 는 등 문제 가 발생 할 수 있 기 때문이다.
4. 귀속
재 귀 함 수 는 자신 을 직접 또는 간접 적 으로 호출 하 는 함수 이다.일반적으로 재 귀 함수 가 자신 을 호출 하여 하위 문 제 를 해결 합 니 다.재 귀 함 수 는 트 리 구 조 를 매우 효율적으로 조작 할 수 있다.예 를 들 어 브 라 우 저의 문서 개체 모델 (DOM) 은 재 귀적 호출 할 때마다 지정 한 트 리 의 일부분 을 처리 합 니 다.
5. 역할 영역
프로 그래 밍 언어 에서 역할 영역 은 변수 와 매개 변수의 가시 성과 생명 주 기 를 제어 한다.이름 충돌 을 줄 이 고 자동 메모리 관 리 를 제공 합 니 다.
var foo = function(){
    var a = 3, b = 5;

    var bar = function(){
        var b = 7, c = 11;

//  ,a = 3, b = 7, c = 11

        a += b + c;
//  ,a = 21, b = 7, c = 11

    }
//  ,a = 3, b = 5, c   
    bar();
//  ,a = 21, b = 5  
}

모든 꽃 괄호 (((와 곶) 중의 어구 집합 은 하나의 블록 에 속 하 는데 그 중에서 정 의 된 모든 변 수 는 코드 블록 밖에서 볼 수 없 으 며 우 리 는 블록 급 역할 영역 이 라 고 부른다.함수 역할 영역 은 이해 하기 쉽 습 니 다 (). 함수 에 정 의 된 매개 변수 와 변 수 는 함수 외부 에서 볼 수 없습니다.
JS 는 블록 급 역할 영역 을 지원 하지 않 습 니 다. 함수 역할 영역 만 지원 합 니 다. 또한 한 함수 의 모든 위치 에서 정 의 된 변 수 는 이 함수 의 어느 곳 에서 나 볼 수 있 습 니 다.
JS 는 블록 급 역할 영역 이 부족 하고 함수 역할 영역 만 지원 하기 때문에 가장 좋 은 방법 은 함수 체 의 상단 성명 함수 에 사용 할 수 있 는 모든 변수 입 니 다.함수 내 모든 위치 에서 정 의 된 변 수 는 함수 내부 어느 곳 에서 나 볼 수 있 기 때문이다.
functin test(){ 
  for(var i=0;i<3;i++){ 
  } 
  alert(i); 
} 
test();

/ / JS 에 블록 급 역할 영역 이 없 기 때문에 i 가 3 으로 팝 업 됩 니 다. 블록 밖에서 블록 에서 정의 하 는 변수 i 는 여전히 접근 할 수 있 습 니 다.
한 함수 에서 정 의 된 변 수 를 기억 하 십 니까? 이 함수 가 호출 되면 변 수 는 삭 제 됩 니 다. 우 리 는 이 특성 으로 JS 의 블록 급 역할 도 메 인 을 모 의 할 수 있 습 니까?
function test(){
  (function(){
     for(var i = 0; i < 3; i++ ){

     }
  })();
  alert(i);
}
test();

오류 가 발생 할 수 있 습 니 다: i is not defined 여기 서 우 리 는 for 구문 블록 을 닫 힌 패키지 에 넣 은 다음 에 이 함 수 를 호출 합 니 다. 함수 호출 이 완료 되면 변수 i 가 자동 으로 소각 되 기 때문에 우 리 는 블록 밖 에 접근 할 수 없습니다.
폐쇄 하 다
역할 필드 의 장점 은 내부 함수 가 외부 함 수 를 정의 하 는 매개 변수 와 변 수 를 방문 할 수 있다 는 것 입 니 다. (this 와 arguments 제외) 너무 아름 답 습 니 다!
더 재 미 있 는 상황 은 내부 함수 가 외부 함수 보다 더 긴 생명 주 기 를 가지 고 있다 는 것 이다.
var myObject = {
    value: 0,
    increment: function( inc ){
         this.value += typeof inc === 'number' ? inc : 1;
    }
}

만약 우리 가 my Object 의 value 값 이 불법 으로 수정 되 지 않도록 보호 하려 면 어떻게 합 니까?
var myObject = (function() {
    var value = 0;

    return {
        increment: function( inc ){
             value += typeof inc === 'number' ? inc : 1;
        },
        getValue: function(){
             return value;
        }     
    };
}());

이 함 수 는 대상 글자 의 양 을 되 돌려 줍 니 다.두 가지 방법 을 포함 하 는 대상 을 되 돌려 주 고 이 방법 들 은 value 변 수 를 방문 하 는 특권 을 계속 누 립 니 다.my Object 의 value 는 increment 와 getValue 방법 에 항상 사용 할 수 있 지만 함수 의 역할 영역 은 다른 프로그램 에 서 는 볼 수 없습니다!!
우 리 는 다시 하나의 예 를 보 자.
var quo = function(status){
    return {
        get_status: function(){
            return status;
        }
    };
};
var myQuo = quo('amazed');
myQuo.get_status();

하나의 유용 한 예: DOM 노드 를 노란색 으로 설정 한 다음 에 흰색 으로 그 라 데 이 션 합 니 다.
var fade = function(node){
    var level = 1;
    var step = function(){
      var hex = level.toString(16);
      node.style.backgroundColor = '#FFFF' + hex + hex;
      if( level < 15 ){
            level++;
            setTimeout(step,100)
      }
    }
    setTimeout(step, 100)
}
fade(document.body);

7 모듈
함 수 를 사용 하여 모듈 을 만 들 면 우 리 는 전역 변수의 사용 을 완전히 배제 하고 이 js 의 최 악의 특성 중 하나 가 가 져 온 영향 을 완화 할 수 있다
모듈 형식 예:
var obj = function(){
    var seq = 0;
    var preFix = '';
    return {
        set_prefix: function(p){
           prefix = String(p)
        },
        set_seq: function(s){
           seq = s;
        }
    }
}

8 급 연결
사실은 함수 내부 return this 를 통 해 함수 의 체인 호출 을 실현 하 는 것 입 니 다.
9. 코 리 화
기억
캐 시 변 수 를 통 해 불필요 한 중복 계산 을 피 합 니 다.

좋은 웹페이지 즐겨찾기