main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
 * 우측의 REPL을 통해 `fakeArr`에 저장되어 있는 객체를 조작해보세요.
 * 마치 배열인 것처럼 보이지만, 실제로 배열은 아닙니다.
 */

// Array.prototype === obj.__proto__ 우회
// Object.defineProperties(Array.prototype, {
//   // `Object.prototype.toString.call()` 우회
//   [Symbol.toStringTag]: {
//     get: () => 'Array',
//   },
//   // `...` 연산자 사용 가능하게
//   [Symbol.isConcatSpreadable]: {
//     value: true
//   }
// });

const fakeArr = Object.create(
  Array.prototype,
  {
    length: {
      value: 0,
      writable: true,
      enumerable: false,
      configurable: false
    }
  }
);

const realArray = [];

realArray.constructor === Array; // true
realArray instanceof Array; // true
Object.prototype.toString.call(realArray); // [object Array]
realArray.__proto__ === Array.prototype; // true
Array.isArray(realArray); // true

fakeArr.constructor === Array; // true
fakeArr instanceof Array; // true
Object.prototype.toString.call(fakeArr); // [object Array]
fakeArr.__proto__ === Array.prototype; // true
Array.isArray(fakeArr); // false (!!!)
Babel Compiler v6.4.4 Copyright (c) 2014-2015 Sebastian McKenzie