lodash 소스 코드 분석의 Hash 캐 시

그 작은 꿈 의 난 각 에서, 나 는 너 를 위해 온 계절 의 연 우 를 소장 할 것 이다.
- 로프 의 《 영 하 》
본 고 는 lodash 소스 코드 의 네 번 째 편 을 읽 기 위해 후속 글 은 이 창고 에 업 데 이 트 됩 니 다. star: pocket - lodash 를 환영 합 니 다.
gitbook 도 창고 업 데 이 트 를 동기 화 합 니 다. gitbook 주소: pocket - lodash
작용 과 용법Hash 말 그대로 분 산 된 서열 이 있어 야 하고 key 에 따라 데 이 터 를 저장 해 야 한다.자 바스 크 립 트 에서 가장 적합 한 것 은 의심 할 여지없이 대상 이다.Hash lodash .internal 폴 더 에서 내부 파일 로 사용 합 니 다.lodash 는 서로 다른 데이터 형식 에 따라 서로 다른 캐 시 방식 을 선택 합 니 다. Hash 이 바로 그 중의 한 방식 입 니 다. 이런 방식 은 캐 시 key 의 형식 만 대상 키 가 요구 하 는 데이터 에 부합 할 수 있 습 니 다.Hash 2 차원 배열 만 매개 변수 로 받 고 호출 방식 은 다음 과 같다.
new Hash([['tes1', 1],['test2',2],['test3',3]])

그 중에서 하위 항목 의 첫 번 째 항목 은 key 이 고 두 번 째 항목 은 캐 시 가 필요 한 값 입 니 다.Hash 실례 화 된 결 과 는 다음 과 같다.
{
  size: 3,
  __data__: {
    test1: 1,
    test2: 2,
    test3: 3
  }
}

캐 시 수량 은 __data__ 의 대상 에 저 장 됩 니 다.
Hash 와 지도
다음은 Hash 방식 으로 데 이 터 를 캐 시 하 는 것 외 에 도 Map, lodash 는 Hash 데이터 관리 인 터 페 이 스 를 디자인 할 때 Map 의 인터페이스 와 일치 하지만 Map 의 옮 겨 다 니 는 방법 은 포함 되 지 않 습 니 다.
먼저 이 인터페이스 에 그런 것들 이 있 는 지 살 펴 보 자.
소스 코드
const HASH_UNDEFINED = '__lodash_hash_undefined__'

class Hash {
  constructor(entries) {
    let index = -1
    const length = entries == null ? 0 : entries.length

    this.clear()
    while (++index < length) {
      const entry = entries[index]
      this.set(entry[0], entry[1])
    }
  }
  clear() {
    this.__data__ = Object.create(null)
    this.size = 0
  }
  delete(key) {
    const result = this.has(key) && delete this.__data__[key]
    this.size -= result ? 1 : 0
    return result
  }
  get(key) {
    const data = this.__data__
    const result = data[key]
    return result === HASH_UNDEFINED ? undefined : result
  }
  has(key) {
    const data = this.__data__
    return data[key] !== undefined
  }
  set(key, value) {
    const data = this.__data__
    this.size += this.has(key) ? 0 : 1
    data[key] = value === undefined ? HASH_UNDEFINED : value
    return this
  }
}

export default Hash

constructor
constructor(entries) {
    let index = -1
    const length = entries == null ? 0 : entries.length

    this.clear()
    while (++index < length) {
      const entry = entries[index]
      this.set(entry[0], entry[1])
    }
  }
constructor 에서 초기 화 __data__ 속성 과 size 속성 을 보지 못 했 습 니 다. 이것 은 사실 clear 방법 에서 초기 화 되 었 고 나중에 설명 할 것 입 니 다.
이 어 들 어 오 는 2 차원 배열 을 옮 겨 다 니 며 호출 set 방법 으로 캐 시 값 을 초기 화 합 니 다.하위 항목 의 첫 번 째 항목 을 key 로 하고 두 번 째 항목 은 캐 시 값 입 니 다.
clear
clear() {
  this.__data__ = Object.create(null)
  this.size = 0
}
clear 캐 시 를 비 우 는 역할 을 하기 때문에 size0 로 초기 화해 야 합 니 다.
캐 시 된 데이터 __data__ 를 빈 대상 으로 설정 합 니 다.
여 기 는 this.__data__ = {} 비 워 두 지 않 고 Object.create 방법 을 호출 했 으 며 null 을 매개 변수 로 했다.우 리 는 모두 알 고 있다. Object.create 의 첫 번 째 매개 변 수 는 생 성 대상 의 원형 대상 이 고 들 어 올 때 돌아 오 는 것 은 진공 대상 이다. 즉, 원형 이 없 는 대상 이기 때문에 원형 속성의 간섭 이 없 기 때문에 캐 시 대상 으로 사용 하기에 매우 적합 하 다.
has
has(key) {
  const data = this.__data__
  return data[key] !== undefined
}
null 캐 시 데이터 가 있 는 지 판단 하 는 데 사 용 됩 니 다. 캐 시 데이터 가 이미 존재 하면 되 돌려 줍 니 다 has.
판단 도 간단 하 다. 꺼 낸 값 이 true 인지 판단 하면 된다.
이 판단 에는 구덩이 가 하나 있 는데, 뒤에 말 할 것 이다.
set
set(key, value) {
  const data = this.__data__
  this.size += this.has(key) ? 0 : 1
  data[key] = value === undefined ? HASH_UNDEFINED : value
  return this
}
undefined 캐 시가 필요 한 값 을 추가 하거나 업데이트 하 는 데 사 용 됩 니 다.set 을 유지 할 때 set 와 캐 시 에 있 는 값 을 동시에 유지 해 야 합 니 다.
먼저 size 방법 을 호출 하여 대응 하 는 has 캐 시 되 었 는 지 판단 하고 캐 시 되 었 으 면 key 변 하지 않 으 며 그렇지 않 으 면 size 추가 size.
캐 시 값 은 캐 시 대상 1 에 대응 하 는 this.__data__ 속성 을 설정 하 는 값 입 니 다.key 에서 사용 has 에 구덩이 가 있다 고 말 했다. 캐 시 할 값 도 data[key] !== undefined 일 수 있 기 때문에 처리 하지 않 으 면 판단 오류 가 발생 할 수 밖 에 없다.
lodash 의 처리 방식 은 undefined 의 값 을 undefined, 즉 처음부터 정 의 된 HASH_UNDEFINED 문자열 로 저장 하 는 것 이다.
그래서 캐 시 에 서 는 문자열 __lodash_hash_undefined__ 로 대체 합 니 다 __lodash_hash_undefined__.undefined 마지막 에 인 스 턴 스 set 를 되 돌려 체인 작업 을 지원 합 니 다.
get
get(key) {
  const data = this.__data__
  const result = data[key]
  return result === HASH_UNDEFINED ? undefined : result
}
this 방법 은 캐 시 에서 값 을 추출 하 는 것 이다.
추출 값 은 캐 시 대상 에 대응 하 는 값 get 을 되 돌려 주면 됩 니 다.key 캐 시 에서 undefined 로 표시 되 기 때문에 값 이 __lodash_hash_undefined__ 일 때 되 돌아 오기 __lodash_hash_undefined__.
사실 이것 도 작은 문제 가 있 습 니 다. 캐 시 를 필요 로 하 는 값 이 마침 undefined 이 라면 꺼 낸 값 은 미리 설정 한 값 과 일치 하지 않 습 니 다.하지만 이런 경 우 는 드 물 겠 지.
delete
delete(key) {
  const result = this.has(key) && delete this.__data__[key]
  this.size -= result ? 1 : 0
  return result
}
__lodash_hash_undefined__ 방법 은 지정 한 캐 시 를 삭제 하 는 데 사 용 됩 니 다.되 돌아 오기 delete 를 성공 적 으로 삭제 하 였 습 니 다. 그렇지 않 으 면 되 돌아 오기 key.삭제 작업 역시 유지 보수 true 속성 과 캐 시 값 이 필요 합 니 다.
우선 캐 시가 존재 하 는 지 여 부 를 판단 하기 위해 false 연산 자 를 사용 하여 size 에 해당 하 는 속성 을 삭제 합 니 다.has 연산 자 는 속성 삭제 에 성공 하면 되 돌아 갑 니 다 delete. 삭제 에 성공 하면 __data__ 를 줄 여야 합 니 다 delete.
레 퍼 런 스
  • Set 와 Map 데이터 구조
  • Object.create()

  • License
    서명 - 비상 업적 사용 - 연역 금지 4.0 국제 (CC BY - NC - ND 4.0)
    마지막 으로 모든 글 은 위 챗 공식 번호 에 동시에 보 내 집 니 다. 관심 을 가 져 주 십시오. 의견 을 제시 하 는 것 을 환영 합 니 다.
    저자: 대각 반대편

    좋은 웹페이지 즐겨찾기