关键字 new 的实现原理

举报
小妖现世 发表于 2021/07/11 23:03:17 2021/07/11
【摘要】 造函数和实例化在 JavaScript 可以通过构造函数批量创建对象,这个创建的过程通过 new 关键字实现,也被称作实例化,对象被创建时会有默认的属性和原型方法。function Person(name, age) { this.name = name; this.age = age;}Person.prototype.sayHi = function () { var output...

造函数和实例化


JavaScript 可以通过构造函数批量创建对象,这个创建的过程通过 new 关键字实现,也被称作实例化,对象被创建时会有默认的属性和原型方法。


function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHi = function () {
  var output = "My name is " + this.name + ", I'm " + this.age + " years old."
  console.log(output);
}

var panda = new Person('panda', 25);

panda.sayHi(); // My name is panda, I'm 25 years old.


new 的过程都做了什么


new 的过程中主要做了 4 件事:


  • 创建一个空对象;
  • 将这个空对象的原型指向构造函数的原型;
  • 执行构造函数,并将默认属性挂载到这个空对象上;
  • 判断构造函数的返回值,如果是对象则返回这个对象,否则返回新创建的对象。


模拟 new 关键字


清楚了构造函数实例化的过程,我们就来手动实现一个 New 函数,来替代关键字 new


// New 函数的第一个参数为构造函数,剩余的参数为实例化传入的参数
function New() {
  var Constructor = Array.prototype.shift.call(arguments);
  var obj = {};
  obj.__proto__ = Constructor.prototype;
  var result = Constructor.apply(obj, arguments);
  return result instanceof Object ? result : obj;
}


var panda = New(Person, 'panda', 25);

console.log(panda); // Person {name: "panda", age: 25}
panda.sayHi(); // My name is panda, I'm 25 years old.


上面的方法已经实现了 new 关键字的功能,但是美中不足的是,不能将构造函数和实例化的参数区分清晰,下面稍微优化一下。


function New(Constructor) {
  return function () {
    var obj = {};
    obj.__proto__ = Constructor.prototype;
    var result = Constructor.apply(obj, arguments);
    return result instanceof Object ? result : obj;
  }
}


var panda = New(Person)('panda', 25);

console.log(panda); // Person {name: "panda", age: 25}
panda.sayHi(); // My name is panda, I'm 25 years old.


与第一种相比只是 New 函数的使用方式有所变化,New 执行后返回一个函数,调用这个返回的函数,才会进行实例化,传入的参数为实例化对象的参数,这样是 New 的功能变的单一,也将构造函数与实例化的参数分开。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。