学习Javascript之模拟实现new

作者 : 开心源码 本文共2673个字,预计阅读时间需要7分钟 发布时间: 2022-05-13 共158人阅读

前言

本文1021字,阅读大约需要5分钟。

总括: 本文对new进行了一个简单详情,而后使用一个函数模拟实现了new操作符做的事情。

  • 参考文档:new 运算符
  • 公众号:「前台进阶学习」,回复「666」,获取一揽子前台技术书籍

人生是没有毕业的学校。

正文

new是JS中的一个关键字,用来将构造函数实例化的一个运算符。例子:

function Animal(name) {    this.name = name;}Animal.prototype.sayName = function() {    console.log("I'm " + this.name);}var cat = new Animal('Tom');console.log(cat.name); // Tomconsole.log(cat.__proto__ === Animal.prototype); // truecat.sayName(); // I'm Tom

从上面的例子可以得出两点结论:

  1. new操作符实例化了一个对象;
  2. 这个对象可以访问构造函数的属性;
  3. 这个对象可以访问构造函数原型上的属性;
  4. 对象的_proto_属性指向了构造函数的原型;

因为new是关键字,我们只能去公告一个函数去实现new的功能,首先实现上面的三个特性,第一版代码如下:

附:对原型原型链不熟习的可以先看了解Javascript的原型和原型链。

// construct: 构造函数function newFunction() {  var res = {};  // 排除第一个构造函数参数  var construct = Array.prototype.shift.call(arguments);  res.__proto__ = construct.prototype;  // 使用apply执行构造函数,将构造函数的属性挂载在res上面  construct.apply(res, arguments);  return res;}

我们测试下:

function newFunction() {  var res = {};  var construct = Array.prototype.shift.call(arguments);  res.__proto__ = construct.prototype;  construct.apply(res, arguments);  return res;}function Animal(name) {    this.name = name;}Animal.prototype.sayName = function() {    console.log("I'm " + this.name);}var cat = newFunction(Animal, 'Tom');console.log(cat.name); // Tomconsole.log(cat.__proto__ === Animal.prototype); // truecat.sayName(); // I'm Tom

一切正常。new的特性实现已经80%,但new还有一个特性:

function Animal(name) {    this.name = name;    return {        prop: 'test'    };}var cat = new Animal('Tom');console.log(cat.prop); // testconsole.log(cat.name); // undefinedconsole.log(cat.__proto__ === Object.prototype); // trueconsole.log(cat.__proto__ === Animal.prototype); // false

如上,假如构造函数return了一个对象,那么new操作后返回的是构造函数return的对象。让我们来实现下这个特性,最终版代码如下:

// construct: 构造函数function newFunction() {  var res = {};  // 排除第一个构造函数参数  var construct = Array.prototype.shift.call(arguments);  res.__proto__ = construct.prototype;  // 使用apply执行构造函数,将构造函数的属性挂载在res上面  var conRes = construct.apply(res, arguments);  // 判断返回类型  return conRes instanceof Object ? conRes : res;}

测试下:

function Animal(name) {    this.name = name;  return {    prop: 'test'    };}var cat = newFunction(Animal, 'Tom');console.log(cat.prop); // testconsole.log(cat.name); // undefinedconsole.log(cat.__proto__ === Object.prototype); // trueconsole.log(cat.__proto__ === Animal.prototype); // false

以上代码就是我们最终对new操作符的模拟实现。我们再来看下官方对new的解释

引用MDN对new运算符的定义:

new 运算符创立一个客户定义的对象类型的实例或者具备构造函数的内置对象的实例。

new操作符会干下面这些事:

  1. 创立一个空的简单JavaScript对象(即{});
  2. 链接该对象(即设置该对象的构造函数)到另一个对象 ;
  3. 将步骤1新创立的对象作为this的上下文 ;
  4. 假如该函数没有返回对象,则返回this

4条都已经实现。还有一个更好的实现,就是通过Object.create去创立一个空的对象:

// construct: 构造函数function newFunction() {  // 通过Object.create创立一个空对象;  var res = Object.create(null);  // 排除第一个构造函数参数  var construct = Array.prototype.shift.call(arguments);  res.__proto__ = construct.prototype;  // 使用apply执行构造函数,将构造函数的属性挂载在res上面  var conRes = construct.apply(res, arguments);  // 判断返回类型  return conRes instanceof Object ? conRes : res;}

以上。


能力有限,水平一般,欢迎勘误,不胜感激。

订阅更多文章可关注公众号「前台进阶学习」,回复「666」,获取一揽子前台技术书籍

前台进阶学习

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 学习Javascript之模拟实现new

发表回复