推理实现new操作符
JavaScript new操作符实现
- 要去设计一个东西,首先要想好你想如何使用它,其次是考虑他的功能。
想如何使用
const zs = myNew(User, 'zs', 18)
很简单,传一个构造函数给我,我返回你一个实例对象,这就是 new
最直接的功能
构造函数(不必多说)
function User(name, age) {this.name = namethis.age = age}User.prototype.show = function () {console.log(this.name, this.age)}
接下来要做的就是思考如何实现 myNew
的功能了
思考
1、myNew
有什么样的功能,其实是你想得到一个什么样的 zs
决定的
- zs本质就是一个对象,所以可以写出如下代码
function myNew(Constructor, ...args) {const instanceObj = {}return instanceObj}
2、通过第一步已经确定主干了,接下来思考 zs
实例对象和User
构造函数之间的关系
- 在使用 js 的
new
操作符时,实例对象的__proto__
会指向构造函数的prototype
,也就是我们要满足以下这种关系
zs.__proto__ === User.prototype //true
- 有了上面的分析,很容易写出以下代码,就是一个赋值操作
instanceObj.__proto__ = Constructor.prototype
- 接下来,我们需要把参数传给构造函数,让其将参数保存在
this
上,我们通过实例对象去访问的时候能够访问到
Constructor(...args)
如果用以上方式传参的话,构造函数内部的 this
在浏览器环境中会指向 window
,所以我们需要改变其内部的 this
指向
Constructor.apply(instanceObj, args)
完整代码
function User(name, age) {this.name = namethis.age = age}User.prototype.show = function () {console.log(this.name, this.age)}function myNew(Constructor, ...args) {const instanceObj = {}instanceObj.__proto__ = Constructor.prototypeConstructor.apply(instanceObj, args)return instanceObj}const zs = myNew(User, 'zs', 18)zs.show()