# 4 个问题可以检测出你 JavaScript 水平的高低

返回:前端进阶

# 实现 Array.prototype.map

它将创建一个新数组,其中将填充在调用数组中每个元素上调用提供的函数的结果

function map(array, iteratee) {
  let index = -1;
  const length = array == null ? 0 : array.length;
  const result = new Array(length);
  while (++index < length) {
    result[index] = iteratee(array[index], index, array);
  }
  return result;
}
1
2
3
4
5
6
7
8
9

# Object.defineProperty 和代理

  • 访问者属性
  • Object.defineProperty
  • 代理

# 访问者属性

let obj = {
  get a() {
    console.log("triggle get a() method");
    console.log("you can do anything as you want");
    return 1;
  },
  set a(value) {
    console.log("triggle set a() method");
    console.log("you can do anything as you want");
    console.log(`you are trying to assign ${value} to obj.a`);
  },
};
1
2
3
4
5
6
7
8
9
10
11
12

访问属性为我们提供了强大的元编程能力,因此我们可以通过以下方式满足我们的要求:

let obj = {
  _initValue: 0,
  get a() {
    this._initValue++;
    return this._initValue;
  },
};

console.log(obj.a, obj.a, obj.a); // 1,2,3
1
2
3
4
5
6
7
8
9

# Object.defineProperty

let obj = {};
Object.defineProperty(obj, "a", {
  get: (function() {
    let initValue = 0;
    return function() {
      initValue++;
      return initValue;
    };
  })(),
});
console.log(obj.a, obj.a, obj.a);
1
2
3
4
5
6
7
8
9
10
11

# 代理

使用代理,我们可以拦截对对象属性的访问。 只要我们使用代理来拦截对 obj.a 的访问,然后依次返回 1、2 和 3,我们就可以在以下条件之前完成要求:

let initValue = 0;
let obj = new Proxy(
  {},
  {
    get: function(item, property, itemProxy) {
      if (property === "a") {
        initValue++;
        return initValue;
      }
      return item[property];
    },
  }
);

console.log(obj.a, obj.a, obj.a);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 范围和闭包