JS new 操作符完整执行过程

张开发
2026/4/11 8:13:39 15 分钟阅读

分享文章

JS new 操作符完整执行过程
JS new 操作符完整执行过程内存原型原型链深度解析new是 JavaScript 中创建实例对象的核心操作符它不是简单的语法糖而是一套内存分配、原型绑定、构造函数执行、返回值处理的完整流程。我会用最通俗的语言 分步拆解 内存/原型/原型链变化把整个过程讲透你看完就能彻底理解。一、先明确基础概念必须懂构造函数普通函数首字母大写约定用来生成实例如function Person(){}原型prototype每个函数都有的属性是一个对象存放实例共享的方法/属性__proto__每个对象都有的隐式原型指向构造函数的prototype是原型链的核心原型链实例通过__proto__逐级向上查找属性/方法的链条终点是Object.prototype再向上是null二、new 操作符 4 步核心执行流程当执行const obj new 构造函数()时JS 引擎会严格按 4 步执行每一步都会改变内存和原型关系第 1 步创建一个全新的空对象// 内部执行创建空对象分配独立堆内存constnewObj{};内存变化在堆内存中开辟一块新空间存储这个空对象栈内存的变量指向这块堆地址原型/原型链此时空对象的__proto__默认指向Object.prototype原生默认规则第 2 步绑定原型链最核心步骤将新对象的隐式原型__proto__指向构造函数的显式原型prototype// 内部执行改写原型指向newObj.__proto__构造函数.prototype;关键变化原型关系实例.__proto__ 构造函数.prototype原型链新对象不再直接继承Object而是继承构造函数的原型原型链被重新串联内存只是修改引用地址不新增内存__proto__是指针指向堆中的原型对象第 3 步执行构造函数绑定 this把构造函数的this强制绑定到第 1 步创建的新对象上并执行构造函数内部代码// 内部执行call 改变 this 指向构造函数.call(newObj);关键变化this 指向构造函数内的this不再指向 window/undefined指向新对象内存构造函数内的this.xxx赋值会直接写入新对象的堆内存中属性区分实例自身属性this.name→ 存在实例对象内存中共享属性构造函数.prototype.say→ 存在原型对象中第 4 步返回实例对象如果构造函数没有手动返回对象JS 自动返回第 1 步创建的新对象如果构造函数手动返回了对象则以手动返回的对象为准基本类型无效仍返回新对象// 最终赋值constobjnewObj;三、完整代码演示 内存/原型/原型链实时变化我们用一个实际例子一步步看所有变化// 1. 定义构造函数函数也是对象有 prototype 属性functionPerson(name){// 构造函数内部this 指向 new 创建的新对象this.namename;// 实例自身属性}// 2. 给构造函数的原型添加方法所有实例共享Person.prototype.sayfunction(){console.log(我是this.name);};// 3. 执行 new 操作符constp1newPerson(张三);执行new Person(张三)全过程拆解1. 创建空对象堆内存生成空对象{}栈变量p1暂存引用2. 绑定原型核心p1.__proto__Person.prototype;✅原型关系成立p1.__proto__ Person.prototype3. 执行构造函数this 绑定Person.call(p1,张三);// 等价于执行p1.name 张三内存空对象变成{ name: 张三 }this完全指向p14. 返回对象p1最终指向这个带属性的对象四、内存分布可视化最关键栈内存存引用地址p1 → 堆内存地址0x100 Person → 堆内存地址0x200堆内存存实际对象# 0x100p1 实例对象自身属性 { name: 张三, __proto__: 0x300 // 指向 Person.prototype } # 0x200Person 构造函数对象 { prototype: 0x300, // 显式原型 __proto__: Function.prototype } # 0x300Person.prototype 原型对象 { say: function(){}, __proto__: Object.prototype, // 原型链向上 constructor: Person } # 0x400Object.prototype 原型链终点 { toString: ..., __proto__: null }五、原型链完整链条一眼看懂执行new后p1的原型链是p1 → Person.prototype → Object.prototype → null验证代码直接复制运行console.log(p1.__proto__Person.prototype);// trueconsole.log(Person.prototype.__proto__Object.prototype);// trueconsole.log(Object.prototype.__proto__);// null原型链终点属性查找规则原型链的作用找p1.name→ 先查实例自身内存→ 找到找p1.say→ 实例自身没有 → 沿__proto__查Person.prototype→ 找到找p1.toString→ 自身没有 → 查Person.prototype没有 → 查Object.prototype→ 找到六、特殊情况构造函数有 return 时的变化new第四步的返回规则return 基本类型数字/字符串/布尔/null/undefined→无效仍返回新对象return 对象{} / [] / 实例→生效覆盖 new 创建的对象原型链失效示例functionPerson(){this.name张三;return{age:18};// 返回对象}constp1newPerson();console.log(p1);// { age: 18 } 不是 Person 实例原型链断裂七、手动实现 new 操作符彻底吃透原理我们用代码还原 new 的 4 步逻辑看完你会 100% 理解functionmyNew(constructor,...args){// 1. 创建空对象constobj{};// 2. 绑定原型obj.__proto__ 构造函数.prototypeObject.setPrototypeOf(obj,constructor.prototype);// 3. 执行构造函数绑定 thisconstresconstructor.apply(obj,args);// 4. 返回如果构造函数返回对象则用它否则返回 objreturnresinstanceofObject?res:obj;}// 测试constp2myNew(Person,李四);p2.say();// 我是李四console.log(p2.__proto__Person.prototype);// true总结核心记忆点new 4 步创建空对象 → 绑定原型 → 绑定 this 执行构造函数 → 返回对象原型核心等式实例.__proto__ 构造函数.prototype内存实例存自身属性原型存共享属性节省内存原型链实例 → 构造函数原型 → Object原型 → nullreturn返回对象会覆盖 new 创建的实例基本类型无效这就是new操作符内存、原型、原型链的全部底层逻辑也是 JS 面向对象的核心基石。

更多文章