常见的手写js

new

new 操作符

new 的原理是什么?通过 new 的方式创建对象和通过字面量创建有什么区别?

在调用new的过程中会发生四件操作

  1. 新建了一个对象
  2. 新对象链接到原型对象上
  3. 绑定 this
  4. 返回这个新对象
1
2
3
4
5
6
7
8
9
10
11
12
function create() {
// 1.创建一个新对象
let obj = {};
// 获取第一个参数,也就是获取构造函数
let Con = [].shift.call(arguments);
// 2.新对象继承构造函数原型对象上的所有方法
obj.__proto__ = Con.prototype;
// 3.构造函数的this指向新对象obj,并将剩余的参数传进去执行,得到结果result
let result = Con.apply(obj, arguments);
// 4.如果得到的结果是个对象的话就返回result,如果不是的话就返回对象obj
return result instanceof Object ? result : obj;
}

关于上面代码的第四条注释:构造函数如果返回原始值,那么这个返回值毫无意义

1
2
3
4
5
6
function Test(name) {
this.name = name;
return 1;
}
const t = new Test("zhl");
console.log(t.name); // 'zhl'

对于创建一个对象来说,更推荐使用字面量的方式创建对象(无论性能上还是可读性)。因为你使用 new Object() 的方式创建对象需要通过作用域链一层层找到 Object,但是你使用字面量的方式就没这个问题。

instanceof 原理

instanceof 的原理是什么?

instanceof 可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找到类型的 prototype

1
2
3
4
5
6
7
8
9
function myInstanceof(left, right) {
let prototype = right.prototype;
left = left.__proto__;
while (true) {
if (left === null || left === undefined) return false;
if (prototype === left) return true;
left = left.__proto__;
}
}

分析:

  • 首先获取类型的原型
  • 然后获得对象的原型
  • 然后一直循环判断对象的原型是否等于类型的原型,直到对象原型为 null,因为原型链最终为 null

防抖与节流

之前看到一个很形象的比喻。节流防抖就好比乘电梯,比如 delay 是 10 秒,防抖就是电梯每进来一个人就要等 10 秒再运行,而节流就是电梯保证每 10 秒可以运行一次


常见的手写js
https://zouhualu.github.io/20220528/常见的手写js/
作者
花鹿
发布于
2022年5月28日
许可协议