📕 重学JavaScript:如何实现一个`new`?

简介: 如何实现一个new的效果呢?

📕 重学JavaScript:如何实现一个new

嗨,大家好!这里是道长王jj~ 🎩🧙‍♂️

看过之前的文章的朋友应该都知道了实例对象和构造对象的关系

这个new其实就是一个关键字,它可以让我们创建一个对象,并把它绑定到一个构造函数上。

比如,我们可以用new来创建一个名字叫Tom的人:

function Person(name) {
   
  this.name = name;

  this.sayHello = function() {
   
    console.log(`Hello, I am ${
     this.name}`);
  };
}

// 使用new关键字,创建一个名字叫Tom的人
let tom = new Person("Tom");
// Hello, I am Tom
tom.sayHello();

那么,如何实现一个new的效果呢?

🔰 思路分析

想要知道new 怎么实现,首先我们得知道它这个过程中,干了些什么事情。

  1. 让实例可以访问到私有属性,也就是构造函数里用this添加的属性

    比如,this.name = name 就是给实例添加了一个私有属性name。👌

  2. 让实例可以访问构造函数原型(constructor.prototype)所在原型链上的属性,也就是构造函数和其他对象共享的属性和方法。

    比如,Person.prototype.sayHello = function() {…}就是给Person构造函数的原型对象添加了一个共享方法sayHello。👌

  3. 判断构造函数返回的结果

    1. 不是引用数据类型,那么就返回实例本身。
    2. 是引用数据类型,那么就返回这个引用数据类型

确定好思路之后,我们就可以进行伪代码环节了。

💫 伪代码思路

1. 创建一个空对象obj
2. 把obj的原型链指向构造函数的原型对象。p1.__proto__ = Person.prototype;
3. 把obj作为this参数传给构造函数,并执行构造函数。constructor.call(obj, ...args);
4. 如果返回值result是引用数据类型,就返回result,否则返回obj

⭕ 代码实现

function myNew(constructor, ...args) {
   
  // 步骤1:创建一个空对象obj
  let obj = {
   };
  // 步骤2:把obj的原型链指向构造函数的原型对象
  obj.__proto__ = constructor.prototype;
  // 步骤3:把obj作为this参数传给构造函数,并执行构造函数,得到返回值result
  let result = constructor.call(obj, ...args);
  // 步骤4:如果返回值result是引用数据类型,就返回result,否则返回obj
  return result instanceof Object ? result : obj;
}

💥 测试一下各种情况看看有没有问题

function Person(name) {
   
  this.name = name;

  this.sayHello = function() {
   
    console.log(`Hello, I am ${
     this.name}`);
  };
}

// 使用myNew函数,创建一个名字叫Tom的人
let tom = myNew(Person, "Tom");
// Hello, I am Tom
tom.sayHello();
// true
console.log(Object.getPrototypeOf(tom) === Person.prototype);


function Animal(type, sound) {
   
  this.type = type;
  this.sound = sound;

  if (type === "cat") {
   
    return {
   name: 'Bob'};
  }
}

// 测试如果是引用数据类型
let dog = myNew(Animal, "dog", "woof");
// dog
console.log(dog.type);
// woof
console.log(dog.sound);
// true
console.log(Object.getPrototypeOf(dog) === Animal.prototype);

// 测试如果不是引用数据类型
let cat = myNew(Animal, "cat", "meow");
// Bob
console.log(cat.name);
// undefined
console.log(cat.type);
// undefined
console.log(cat.sound);
// true
console.log(Object.getPrototypeOf(cat) === Object.prototype);

🎉 你觉得怎么样?这篇文章可以给你带来帮助吗?如果你有任何疑问或者想进一步讨论相关话题,请随时发表评论分享您的想法,让其他人从中受益。🚀✨

目录
相关文章
|
6月前
|
JavaScript 前端开发 Java
【面试题】new 一个对象时,js 做了什么?
【面试题】new 一个对象时,js 做了什么?
|
2月前
|
JavaScript
ES6学习(9)js中的new实现
ES6学习(9)js中的new实现
|
15天前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
6月前
|
JavaScript 前端开发
探索JavaScript中的New操作符:原理与使用
探索JavaScript中的New操作符:原理与使用
|
JavaScript
JS new操作符的具体干了什么?
JS new操作符的具体干了什么?
55 1
|
6月前
|
JavaScript 前端开发
javascript中new关键字的本质是什么
javascript中new关键字的本质是什么
|
JavaScript 前端开发 API
JavaScript中的new,bind,call,apply的原理及简易实现
JavaScript中的new,bind,call,apply的原理及简易实现
97 0
|
JavaScript 前端开发
JavaScript 使用对象字面量创建对象、使用new Object创建对象
JavaScript 使用对象字面量创建对象、使用new Object创建对象
133 0
|
JavaScript
JS 构造函数在 new 时做了啥?
JS 构造函数在 new 时做了啥?
71 0
|
6月前
|
JavaScript 前端开发 Java
JavaScript难点:原型、原型链、继承、new、prototype和constructor
JavaScript 不像 Java、C++ 这种纯面向对象的语言,可以通过类实现继承,JavaScript中的继承是通过原型实现的,即使 ES6 中新增的 class 类也只是原型的语法糖而已
79 4