0%

JavaScript深入之new的模拟实现

new实例化

  • 返回一个新的对象
  • 新对象可以访问构造函数里的属性和方法
  • 新对象可以访问 prototype 上的属性和方法

初步实现

因为 new 是关键字,所以无法像 bind 函数一样直接覆盖,所以我们写一个函数,命名为 mockNew,来模拟 new 的效果。

1
2
3
4
5
6
7
8
9
10
11
12
function mockNew() {
// 需要返回的对象
var obj = new Object();
// 获取需要实例化的构造函数
// shift 会返回构造函数,修改原数组,所以 arguments 会被去除第一个参数
var Constructor = [].shift.call(arguments);
// 继承原型上的属性和方法
obj.__proto__ = Constructor.prototype;
//继承构造函数的属性和方法
Constructor.apply(obj, arguments);
return obj;
}

兼容返回值类型

我们还需要判断构造函数的返回值,如果构造函数的返回值是一个引用类型的对象,我们就返回构造函数的返回值,如果不是,我们该返回什么就返回什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function mockNew() {
// 需要返回的对象
var obj = new Object();
// 获取需要实例化的构造函数
// shift 会返回构造函数,修改原数组,所以 arguments 会被去除第一个参数
var Constructor = [].shift.call(arguments);
// 继承原型上的属性和方法
obj.__proto__ = Constructor.prototype;
// 继承构造函数的属性和方法
var result = Constructor.apply(obj, arguments);
// 兼容返回值类型
// 如果构造函数的返回值是一个引用类型的对象,我们就返回构造函数的返回值,否则返回obj
return result instanceof Object ? result : obj;
}

参考

https://github.com/mqyqingfeng/Blog/issues/13

-------------本文结束感谢您的阅读-------------