Js 常见的小提问

259 阅读2分钟

记录一些 JS 相关的内容,不复杂的技术点会收录在这里。

JavaScript Symbol 类型

Symbol 是ES6中新增的基础类型,本身可以生成一个独一无二的值。利用这个特性,其用处可以是:

  1. 作为对象的私有属性,避免外界调用
  2. 消除魔术字符串
  3. 作为唯一变量名使用,避免命名冲突

参考

实现 new 操作符 ?

首选得知道 new 是干啥的,为啥要用 new。一个函数如果你不用 new 调用,这个函数只是一个普通的函数。

一旦用了 new 以后,一切都变得不一样了。这个函数将被视为构造函数,不管它有没有 return 都会得到一个实例,构造函数被调用时,里面的 this 会指向这个实例。

而且构造函数有它的原型 prototype,new 出来的实例会自动继承 prototype 上的方法,滔滔不绝。

So 只需要按以上的步骤实现即可,非常简单:

  • 创建一个新的对象实例
  • 用构造函数初始化这个实例
  • 继承构造函数 prototype 的原型
  • 返回这个对象实例
function myNew(constructor, data) {
    let obj = {}
    constructor.call(obj, data);
    Object.setPrototypeOf(obj, constructor.prototype);
    return obj;
}

判断 Array 类型的方法

Object.prototype.toString.call([])
Array.isArray([])

实现 call \ apply \ bind ?

实现原理:利用 “this 永远指向最后调用它的那个对象 参考” 特点,只需要弄一个对象方法,来调用 “需要改变 this 指向的方法” 就行。

// apply 和 call 类似,只是传参方式不一样
Function.prototype.myCall = function(context = window, ...args) {
  context = typeof context === "object" ? context : new String(context);
  context.fn = this;
  let res = context.fn(...args);
  delete context.fn;
  return res;
};
Function.prototype.myBind = function(context = window) {
  context = typeof context === "object" ? context : new String(context);
  context.fn = this;
  let args = arguments[1];
  return function() {
    let res = context.fn(...args);
    delete context.fn;
    return res;
  };
};

Proxy 和 Object.defineproperty 的优劣

Proxy 的优势

  • 可以直接监听一整个对象,包括数组,而非属性。
  • 有多达13中拦截方法,如apply, ownKeys, has, deleteProperty

Object.defineproperty 的优势

  • 兼容性好,支持 IE9