手写 new |刷题打卡
手写 new
- 掘金团队号上线,助你 Offer 临门! 点击 查看详情
闲时要有吃紧的心思,忙时要有悠闲的趣味
目录
-
前言
-
正文
- new
- 实现 new
-
总结
-
参考文档
前言
返回目录
如题。
正文
new
返回目录
详情请参考:new 运算符 | MDN
new
运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
语法:
new constructor[([arguments])]
参数:
constructor
一个指定对象实例的类型的类或函数。arguments
一个用于被 constructor 调用的参数列表。
返回值:
一个包含构造函数(父对象)属性和方法的新对象。
使用:
function Car(make, model, year) {
this.make = make
this.model = model
this.year = year
}
const car1 = new Car('Eagle', 'Talon TSi', 1993)
console.log(car1.make)
// Eagle
实现过程
new 关键字会进行如下的操作:
- 创建一个空的简单 JavaScript 对象(即{});
- 链接该对象(设置该对象的 constructor)到另一个对象 ;
- 将步骤上 1 新创建的对象作为 this 的下文 ;
- 如果该函数没有返回对象,则返回 this。
实现 new
返回目录
代码实现:
function myNew(fn, ...args) {
// 1.创建一个空对象obj
const obj = {}
// 2.配置原型链:使用setPrototypeOf更改新建对象obj的原型对象,将其指向fn的原型对象
// 这样obj就能访问构造函数原型所在原型链上的属性了
Object.setPrototypeOf(obj, fn.prototype)
// 3.通过apply使this指向obj,执行函数fn并且获取执行后的结果
let result = fn.apply(obj, args)
// 4.判断result是否为对象,是则返回result,否则返回新创建obj
return result instanceof Object ? result : obj
}
测试:
const car1 = new Car('Eagle', 'Talon TSi', 1993)
const car2 = myNew(Car, '五菱', '五菱宏光', 2020)
console.log('car1', car1)
console.log('car2', car2)
__proto__
详情请参考:Object.prototype.proto(已废弃) | MDN
__proto__
属性(前后各两个下划线),用来读取或设置当前对象的 prototype 对象。
该属性没有写入 ES6 的正文,而是写入了附录,原因是 __proto__
前后的双下划线,说明它本质是一个内部属性,而不是一个正式的对外的 API,只是由于浏览器广泛支持,才被加入 ES6。标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而是从兼容性的角度,都不要使用这个属性,而是使用 Object.setPrototypeOf() (写操作)、Object.getPrototypeOf()(读操作)、Object.create(生成操作)代替。
// es6 的写法
const obj = {
method: function() { ... }
};
obj.__proto__ = someOtherObj;
// es5 的写法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };
setPrototypeOf
详情请参考:Object.setPrototypeOf() | MDN
Object.setPrototypeOf()
方法的作用与 __proto__
相同,用来设置一个对象的 prototype 对象,返回参数对象本身,它是 ES6 正式推荐的设置原型对象的方法。
// 格式
Object.setPrototypeOf(object, prototype)
// 用法
const o = Object.setPrototypeOf({}, null)
总结
返回目录
路漫漫其修远兮,与诸君共勉。
参考文档、
-
jsliang 求职系列 - 11 - 手写 new | 掘金 | jsliang
-
ES6-对象的扩展-proto 属性,Object.setPrototypeOf(),Object.getPrototypeOf()| CSDN - 宋极北
后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址
文档协议
db 的文档库 由 db 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/danygitgit上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。