网站首页 > 技术文章 正文
前言
当我们在使用构造函数的时候,要实例化一个对象,直接使用new就好了,这样新对象就继承到了构造函数的所有属性和方法。那你有思考过new是啥嘛?它的工作流程是什么样的?这也是在前端面试中经常考的一道手写题,今天就让我们一起拿下它!
new是什么?
在手写new之前,让我们先来好好认识一下new是什么!
new 操作符在 JavaScript 中用于创建一个用户定义的对象类型的实例或已有内置对象类型的实例。
new的执行步骤
1.创建新对象
首先,new 操作符会创建一个新的空对象 {}。这个对象将作为新实例的基础。
- 设置原型链
接下来,新创建的对象会被链接到构造函数的 prototype 属性所指向的对象。这意味着新对象将继承构造函数原型上的所有属性和方法。
function Person(name) {
this.name = name;
}
const person1 = new Person('Alice');
console.log(person1.__proto__ === Person.prototype); // true
- 执行构造函数
然后,构造函数被调用,并且 this 被绑定到新创建的对象上。构造函数可以为新对象添加属性和方法
function Person(name) {
this.name = name;
this.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
}
const person1 = new Person('Alice');
person1.sayHello(); // 输出: Hello, my name is Alice
4. 返回新对象
最后,如果构造函数没有显式返回对象,则 new 操作符会自动返回新创建的对象。如果有返回值并且是对象类型(包括函数),则返回该对象;如果是非对象类型(如字符串、数字等),则忽略并返回新创建的对象。
function Person(name) {
this.name = name;
// 如果返回的是对象,则返回该对象
return { name: 'Override' };
}
const person1 = new Person('Alice');
console.log(person1.name); // 输出: Override
function AnotherPerson(name) {
this.name = name;
// 如果返回的是非对象类型,则忽略并返回新创建的对象
return 'Not an object';
}
const anotherPerson = new AnotherPerson('Bob');
console.log(anotherPerson.name); // 输出: Bob
手写new
了解完new的执行步骤,那让我们开始直接手写一个new来更好的理解new吧! 第一步 先随便写一个构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name)
}
在构造函数中我们写了name和age属性,并在Person的原型对象上写了sayName方法。
第二步
要写一个手写new,我的思路就是根据new的四个执行步骤来就行,那么我们第二部就是要创建一个新的空对象
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name)
}
function objectFactory() {
const obj = {};
}
第三步
设置原型链
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name)
}
function objectFactory() {
const obj = {};//空对象的创建
const Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
Constructor.apply(obj, arguments);
}
let awei = objectFactory(Person, 'awei', 23)
console.log(awei);
这里我们用 const Constructor = [].shift.call(arguments); Constructor来提取第一个参数,let awei = objectFactory(Person, 'awei', 23) 可以看到传入的第一个参数是构造函数Person 这时候我们只需要将空对象的原型指向构造函数的原型对象就完成了原型链的设置了obj.__proto__ = Constructor.prototype;
第四步 设置返回值
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name)
}
function objectFactory() {
const obj = {};
const Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
Constructor.apply(obj, arguments);
return obj;
}
let awei = objectFactory(Person, 'awei', 23)
console.log(awei)
这样我们就实现了new的四个执行步骤,让我们来看看结果吧
总结
有需要的小伙伴可以点此资料获取完整版PDF
new 做了什么?
- 在构造器内部创建一个新的对象
- 这个对象内部的隐式原型指向该构造函数的显式原型
- 让构造器中的 this 指向这个对象
- 执行构造器中的代码
- 如果构造器中没有返回对象,则返回上面的创建出来的对象
猜你喜欢
- 2025-09-03 网页数据如何获取,带你走近JS逆向,完全入门级!
- 2025-06-10 告别JSON.stringify,一行代码搞定JavaScript深拷贝的正确姿势!
- 2025-06-10 常见web安全问题,SQL注入、XSS、CSRF,基本原理以及如何防御
- 2025-06-10 web前端之null和undefined区别(前端null与undefined区别)
- 2025-06-10 Why does Google prepend while(1); to their JSON responses?
- 2025-06-10 Map与Set:JavaScript的数据魔术师,让你的代码性能原地起飞!
- 2025-06-10 JavaScript 数据类型详解:从基础到进阶,一篇全搞定!
- 2025-06-10 JS对象判空的几种方式,你真的会了吗?
- 2024-07-30 JavaScript面向对象核心知识归纳(javascript面向对象编程)
- 2024-07-30 前端教程:Javascript Boolean对象
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)