JavaScript 고급 프로 그래 밍 - 요약 노트 - 7

13029 단어 자바 script
고급 용법
1. 안전 한 유형 검사
function isArray (value) {
  return Object.prototype.toString.call(value) === '[Object Array]'
}
function isFunction (value) {
  return Object.prototype.toString.call(value) === '[Object Function]'
}
function isRegExp (value) {
  return Object.prototype.toString.call(value) === '[Object RegExp]'
}

이런 방법 은 한 대상 이 어떤 유형의 원생 대상 인지 검사 할 수 있다.전 제 는 Object. prototype. toString () 방법 이 수정 되 지 않 았 다 는 것 이다. 웹 에서 원생 대상 과 비 원생 대상 을 구분 할 수 있 는 것 이 중요 하 다.이렇게 해야만 어떤 대상 이 도대체 어떤 기능 을 가지 고 있 는 지 확실히 알 수 있다.
2. 역할 영역 안전 한 구조 함수
이 유 는 다음 과 같다.
function Person (name, age, job) {
  this.name = name
  this.age = age
  this.job = job
}
var Person = new Person('wfc', 25, 'frontend')

new 연산 자 를 사용 하 는 것 을 잊 어 버 리 면 구조 함수 의 this 는 전역 window 를 가리 키 며 window 대상 에 추가 속성 을 추가 하여 다른 유용 한 속성 을 덮어 쓰 는 데 오류 가 발생 할 수 있 습 니 다.안전 한 방법:
function Person (name, age, job) {
  if (this instanceof Person) {
    this.name = name
    this.age = age
    this.job = job
  } else {
    return new arguments.callee(name, age, job)
  }
}

이렇게 처리 한 후에 구조 함수 모델 로 만 계승 하면 문제 가 생 길 수 있 습 니 다.
function Person (name, age, job) {
  this.name = name
  this.age = age
  this.job = job
}
function Student (name, age, job, sex) {
  Person.call(this, name, age, job)
  this.sex = sex
}
var ming = new Student('ming', 12, 'student', 'male')
console.log(ming.name) // undefined

그래서 역할 영역 안전 한 구조 함 수 를 사용 하여 다음 과 같은 조 치 를 취해 야 한다.
function Person (name, age, job) {
  this.name = name
  this.age = age
  this.job = job
}
function Student (name, age, job, sex) {
  Person.call(this, name, age, job)
  this.sex = sex
}
Student.prototype = new Person()
var gang = new Student('gang', 13, 'student', 'male')
console.log(ming.name) // 'gang'

3. 불활성 불 러 오기 함수
예:
function createXHR () {
  if (typeof XMLHttpRequest != undefined) { //      ==    ,             ,safari      'object',      'function'
    return new XMLHttpRequest()
  } else if (typeof ActiveXObject != undefined) {
    if (typeof arguments.callee.activeXString != 'string') {
      var versions = [
        'MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'
      ]
      for (var i = 0, len = versions.length; i < len; i++) {
        try {
          new ActiveXObject(versions[i]);
          arguments.callee.activeXString = versions[i];
          break;
        } catch (ex) {}
      }
    } else {
      return new ActiveXObject(arguments.callee.activeXString)
    }
  } else {
    throw new Error('no XHR object available')
  }
}

주: IE7 + 원생 지원 XML HttpRequest 대상.createXHR () 를 호출 할 때마다 브 라 우 저가 지원 하 는 능력 을 검사 하지만, 사실 처음 불 러 올 때 한 번 만 검사 하면 이 브 라 우 저가 어떤 XHR 대상 을 지원 하 는 지 확인 할 수 있 습 니 다.함수 가 실 행 된 지점 을 타성 으로 불 러 오 는 것 은 한 번 뿐 입 니 다.방법 1:
function createXHR () {
  if (typeof XMLHttpRequest != undefined) {
    createXHR = function () {
      return new XMLHttpRequest()
    }
  } else if (typeof ActiveXObject != undefined) {
    var versions = [
      'MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'
    ]
    for (var i = 0, len = versions.length; i < len; i++) {
      try {
        new ActiveXObject(versions[i]);
        createXHR = function () {
          return new ActiveXObject(versions[i]);
        }
        break;
      } catch (ex) {}
    }
  } else {
    createXHR = function () {
      throw new Error('No XHR object available')
    }
  }
  return createXHR()
}

방법 2:
var createXHR = (function () {
  if (typeof XMLHttpRequest != undefined) { //      ==    ,             ,safari      'object',      'function'
    return function () {
      return new XMLHttpRequest()
    }
  } else if (typeof ActiveXObject != undefined) {
    var versions = [
      'MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'
    ]
    for (var i = 0, len = versions.length; i < len; i++) {
      try {
        new ActiveXObject(versions[i]);
        return function () {
          return new ActiveXObject(versions[i]);
        }
        break;
      } catch (ex) {}
    }
  } else {
    throw new Error('no XHR object available')
  }
}())

4. 함수 귀속
함수 바 인 딩 이란 새로운 함 수 를 만 드 는 것 을 말 합 니 다. 특정한 this 환경 에서 지정 한 매개 변수 로 다른 함 수 를 호출 할 수 있 습 니 다.예:
function bind (fn, context) {
  return function () {
    return fn.apply(context, arguments)
  }
}
this.name = 'wfc'
var obj = {
  name: 'abc',
  sayName: function () {
    console.log(this.name)
  }
}
obj.sayName() // 'abc'
var newSayName = bind(obj.sayName, this)
newSayName() // 'wfc'

es5 는 모든 함수 에 원생 의 bid () 방법 을 정의 했다.바 인 딩 된 함 수 는 일반 함수 에 비해 더 많은 분 양 이 있 습 니 다. 더 많은 메모리 가 필요 합 니 다. 또한 다 중 함수 호출 이 조금 느 리 기 때문에 필요 할 때 만 사용 하 는 것 이 좋 습 니 다. /지원 하 는 브 라 우 저 는 IE 9 +, Chrome, Firefox 4 +, Safari 5.1 +, Opera 11.6 + 입 니 다.
5. 원생 bind () 방법
bid () 방법 은 새 함 수 를 만 들 것 입 니 다.이 새 함수 가 호출 될 때 bind () 의 첫 번 째 매개 변 수 는 실 행 될 때의 this 로 되 어 있 으 며, 그 후의 일련의 매개 변 수 는 전 달 된 실제 인삼 앞에서 매개 변수 로 전 달 됩 니 다.문법: fun. bind (thisArg [, arg 1 [, arg 2 [,...]]]]) 예:
this.x = 9;
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); //    81

var retrieveX = module.getX;
retrieveX(); //    9,       ,"this"       

//        , "this"   module  
//          x   module    x   
var boundGetX = retrieveX.bind(module);
boundGetX(); //    81

편 함수 (Partial Functions) bind () 의 또 다른 가장 간단 한 용법 은 함수 가 미리 설 정 된 초기 인 자 를 가지 도록 하 는 것 이다.예:
function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37);

var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]

기본적으로 window. setTimeout () 을 사용 할 때 this 키 워드 는 window (또는 전역) 대상 을 가리 킵 니 다.클래스 를 사용 할 때 this 참조 클래스 의 인 스 턴 스 가 필요 합 니 다. 인 스 턴 스 를 계속 사용 하기 위해 서 는 this 를 반전 함수 에 명시 적 으로 연결 해 야 할 수도 있 습 니 다.
function LateBloomer() {
  this.petalCount = Math.ceil(Math.random() * 12) + 1;
}

// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
  window.setTimeout(this.declare.bind(this), 1000);
};

LateBloomer.prototype.declare = function() {
  console.log('I am a beautiful flower with ' +
    this.petalCount + ' petals!');
};

var flower = new LateBloomer();
flower.bloom();  //     ,   'declare'  

6. 함수 커 리 화 (function currying)
함수 코 리 화 (function currying) 는 하나 이상 의 매개 변 수 를 설정 한 함 수 를 만 드 는 데 사 용 됩 니 다.예:
function curry(fn) {
  var args = Array.prototype.slice.call(arguments, 1)
  return function () {
    var newArgs = args.concat(Array.prototype.slice.call(arguments))
    fn.apply(undefined, newArgs)
  }
}

혹은
function curry(fn, context) {
  var args = Array.prototype.slice.call(arguments, 2)
  return function () {
    var newArgs = args.concat(Array.prototype.slice.call(arguments))
    fn.apply(context, newArgs)
  }
}

es5 의 bind () 방법 은 함수 코 리 화 를 실현 할 수 있다.구체 적 으로 하나 보 자.주의해 야 할 것 은 bind () curry () 를 남용 해 서 는 안 된다 는 것 이다. 왜냐하면 모든 함수 가 추가 비용 을 가 져 오기 때문이다.
7. 대상 을 확장 할 수 없습니다.
기본적으로 모든 대상 은 확장 할 수 있 습 니 다.Object. preventExtensions (obj) 는 대상 에 게 새로운 속성 과 방법 을 추가 하 는 것 을 막 을 수 있 습 니 다.그러나 기 존의 속성 과 방법 은 아무런 영향 을 받 지 않 고 수정 되 고 삭 제 될 수 있다.Object. is Extensible () 은 대상 을 확장 할 수 있 는 지 확인 할 수 있 습 니 다.예:
var obj = {
  name: 'wfc'
}
Object.isExtensible(obj) // true
Object.preventExtensions(obj)
obj.age = 18
obj.age // undefined
Object.isExtensible(obj) // false
obj.name = 'ming'
obj.name // 'ming'
delete obj.name // true
obj.name // undefined

8. 밀 폐 된 대상.
es5 를 대상 으로 정의 하 는 두 번 째 보호 단 계 는 밀봉 대상 이다.밀봉 대상 은 확장 할 수 없고 모든 구성원 의 [Configurable] 특성 이 false 로 설정 되 어 있 습 니 다. 이것 은 대상 을 삭제 할 수 없 음 을 의미 하지만 속성 값 은 수정 할 수 있 습 니 다.대상 을 밀봉 하 는 방법 은 Object. seal () 검 측 대상 이 밀봉 되 었 는 지 여 부 를 검사 하 는 방법 은 Object. isSealed () 모든 밀봉 대상 이 Object. isExtensible () 검 측 으로 false 입 니 다.예:
var person = {
  name: 'gang'
}
Object.isSealed(person) // false
Object.seal(person)
Object.isSealed(person) // true
Object.isExtensible(person) // false
person.name = 'wang'
person.name // 'wang'
delete person.name // false
person.name // 'wang'

그러나 null 또는 undefined 로 할당 할 수 있 습 니 다:
person.name = null
person.name // null
person.name = undefined
person.name // undefined

9. 얼 어 붙 은 대상
가장 엄격 한 변경 방지 등급 은 동결 이다.동 결 된 대상 은 확장 할 수 없 을 뿐만 아니 라 밀봉 할 수 있 으 며 대상 데이터 속성 [[Writable] 특성 은 false 로 설 정 됩 니 다.대상 을 동결 하 는 방법 은 Object. freeze () 에서 대상 의 동결 여 부 를 검사 하 는 방법 은 Object. isFrozen () 과 같다.
var person = {
  name: 'wang'
}
Object.freeze(person)
Object.isFrozen(person) // true
delete person.name // false
person.name // 'wang'
person.name = 'gang'
person.name // 'wang'

JS 라 이브 러 리 작성 자 에 게 동결 대상 은 유용 하 다.JS 라 이브 러 리 는 누군가가 의외로 (또는 의도 적 으로) 핵심 대상 을 수정 하 는 것 을 가장 두려워 하기 때문이다.
10. 타이머
   setTimeout()               。
   setInterval()                    。

11. 함수 순환 분할
이런 순환 에 대해 서.
for (var i = 0, len = arr.length; i < len; i++) {
  process(arr[i])
}

프로 세 스 () 를 완성 하 는 시간 이 길 면 다음 과 같이 분할 할 수 있 습 니 다.
function chunk (arr, process, context) {
  setTimeout(function () {
    var item = arr.shift()
    process.call(context, item)

    if (arr.length > 0) {
      setTimeout(arguments.callee, 100)
    }
  }, 100)
}

일단 어떤 함수 가 50ms 이상 을 써 서 처리 해 야 한다 면 분할 처리 할 수 있 는 지 를 봐 야 한다.
12. 함수 절 류.
브 라 우 저의 일부 계산 과 처 리 는 다른 것 보다 훨씬 비싸다. 예 를 들 어 DOM 작업 은 비 DOM 상호작용 보다 더 많은 메모리 와 CPU 시간 이 필요 하 다.함수 절 류 뒤의 기본 사상 은 일부 코드 가 중단 되 지 않 은 상태 에서 연속 으로 반복 되 어 서 는 안 된다 는 것 이다.예 를 들 어 연속 으로 반복 되 는 resize 이벤트.다음은 이 모델 의 기본 형식 이다.
var processor = {
  timeoutId: null,
  performProcessor: function () {
    handleProcess()
  },
  process: function () {
    clearTimeout(this.timeoutId)

    var that = this
    this.timeoutId = setTimeout(function () {
      that.performProcessor()
    }, 100)
  }
}

함수 사용
function throttle (method, context) {
  clearTimeout(method.tid)
  method.tid = setTimeout(function () {
    method.call(context)
  }, 100)
}

코드 가 주기 적 으로 실행 된다 면 절 류 를 사용 해 야 하지만 요청 이 실행 되 는 속 도 를 조절 할 수 없습니다.여기 throttle () 함 수 는 100 ms 로 간격 을 두 고 수요 에 따라 변경 할 수 있 습 니 다.
13. 사용자 정의 이벤트
정의:
function EventTarget () {
  this.handlers = {}
}

EventTarget.prototype = {
  constructor: EventTarget,
  addHandler: function (type, handler) {
    if (typeof this.handlers[type] === 'undefined') {
      this.handlers[type] = []
    }
    this.handlers[type].push(handler)
  },
  fire: function (event) {
    if (!event.target) {
      event.target = this
    }
    if (this.handlers[event.type] instanceof Array) {
      var handlers = this.handlers[event.type]
      for (var i = 0, len = handlers.length; i < len; i++) {
        handlers[i](event)
      }
    }
  },
  removeHandler: function (type, handler) {
    if (this.handlers[type] instanceof Array) {
      var handlers = this.handlers[type]
      for (var i = 0, len = handlers.length; i < len; i++) {
        if (handlers[i] === handler) {
          handlers.splice(i, 1)
          break
        }
      }
    }
  }
}

사용:
function handleMessage (event) {
  console.log(event.message)
}
var target = new EventTarget()
target.addHandler('message', handleMessage)
target.fire({
  type: 'message',
  message: 'Hello'
}) // 'hello'
target.removeHandler('message', handleMessage)
target.fire({
  type: 'message',
  message: 'Hello'
}) // 'undefined'

다른 용법:
function Person (name, age) {
  EventTarget.call(this)
  this.name = name
  this.age = age
}
Person.prototype = Object.create(EventTarget.prototype)

Person.prototype.say = function (message) {
  this.fire({
    type: 'message',
    message: message
  })
}
var li = new Person('li', 18)
li.addHandler('message', handleMessage)
li.say('hahaha') // 'hahaha'

코드 에 여러 부분 이 특정 시간 에 서로 상호작용 을 하 는 상황 에서 사용자 정의 이벤트 가 매우 유용 합 니 다.사용자 정의 이 벤트 를 사용 하면 연근 관련 대상 을 연결 하고 기능 의 차단 을 유지 하 는 데 도움 이 된다.
  《JavaScript      (   )》   ,             ,  ,              。

좋은 웹페이지 즐겨찾기