这篇文章给大家分享的是有关JavaScript模拟实现new关键字的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。
最近工作太忙,快接近两周没更新博客,总感觉有一些事情等着自己去做,虽然工作内容对自己提升挺大,但我总觉得,一直埋着头走路,偶尔也需要抬起头来,看看现在和自己的期望向是否脱轨,所以周末还是选择来星巴克写些文字。
今天记录 JavaScript 中 new 关键字的模拟实现,当我们在模拟实现某个语言行为之前,应该想想这个行为都做了哪些事情,通过实践,最后也能更加掌握知识点,这就是很多面试题都会问到模拟实现的原因,目的是为了考察候选人知识的深度。
function Person(name) {
this.name = name;
}
var person = new Person('jayChou');
typeof(person) // "object"
person instanceof Person // true
person.__proto__ === Person.prototype // true
person.constructor === Person // true
person.constructor === Person.prototype.constructor // true
以上,可以看出:
new 创建并返回了一个新对象,是构造函数的实例
对象的实例的构造函数属性其实是构造函数的原型对象的 constructor 属性
对象实例的 __proto__ 关联到构造函数的原型对象
上面的内容有关于 JavaScript 中原型对象和原型链的知识,不够清楚的同学可以查看我之前的博客。
由于 new 是 JS 的一个关键字,我们无法实现关键字,但我们可以通过函数的形式来模拟 new 关键字的行为。
知道 new 关键字做了哪些工作,那我们就有了模拟实现的基本思路。
/**
* 模拟实现 JavaScript new 操作符
* @param {Function} constructor [构造函数]
* @return {Object|Function|Regex|Date|Error} [返回结果]
*/
function mockNew() {
// 创建一个空对象
let resultObj = new Object();
// 取传入的第一个参数,即构造函数,并删除第一个参数。
let constructor = Array.prototype.shift.call(arguments);
// 类型判断,错误处理
if(typeof constructor !== "function") {
throw("构造函数第一个参数应为函数");
}
// 绑定 constructor 属性
resultObj.constructor = constructor;
// 关联 __proto__ 到 constructor.prototype
resultObj.__proto__ = constructor.prototype;
// 将构造函数的 this 指向返回的对象
constructor.apply(resultObj, arguments);
// 返回对象
return resultObj;
}
function Person(name) {
this.name = name;
}
var person = mockNew(Person, "jayChou");
console.log(person);
// constructor: ƒ Person(name)
// name: "jayChou"
// __proto__: Object
基本思路正确! 所以我们完成了 new 关键字的初步模拟。伙伴们可以自己动手敲一下,每句代码自己是否都能理解。
构造函数也是函数,有不同类型返回值。有时候构造函数会返回指定的对象内容,所以要对这部分进行处理。
/**
* 模拟实现 JavaScript new 操作符
* @param {Function} constructor [构造函数]
* @return {Object|Function|Regex|Date|Error} [返回结果]
*/
function mockNew() {
// 创建一个空对象
let emptyObj = new Object();
// 取传入的第一个参数,即构造函数,并删除第一个参数。
// 关于为什么要用 Array.prototype.shift.call 的形式,见之前的博客文章 《JavaScript之arguments》
let constructor = Array.prototype.shift.call(arguments);
// 类型判断,错误处理
if(typeof constructor !== "function") {
throw("构造函数第一个参数应为函数");
}
// 绑定 constructor 属性
emptyObj.constructor = constructor;
// 关联 __proto__ 到 constructor.prototype
emptyObj.__proto__ = constructor.prototype;
// 将构造函数的 this 指向返回的对象
let resultObj = constructor.apply(emptyObj, arguments);
// 返回类型判断, 如果是对象,则返回构造函数返回的对象
if (typeof resultObj === "object") {
return resultObj
}
// 返回对象
return emptyObj;
}
function Person(name) {
this.name = name;
return {
name: this.name,
age: 40
}
}
var person = mockNew(Person, "jayChou");
console.log(person);
// {name: "jayChou", age: 40}
// age: 40
// name: "jayChou"
// __proto__: Object
当返回值返回了一个自定义对象后,模拟 new 函数就返回该自定义对象。
JavaScript new 关键字的意义在于让普通函数生成一个新对象,并将对象实例的 __proto__
关联到函数的 prototype 对象。
感谢各位的阅读!关于JavaScript模拟实现new关键字的方法就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到吧!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。