最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS中new操作符的完整執(zhí)行過程

 更新時間:2026年04月12日 14:45:08   作者:五味子1314  
文章詳細(xì)解釋了JavaScript中new操作符的工作原理,包括構(gòu)造函數(shù)、原型、原型鏈等基礎(chǔ)概念,新對象的創(chuàng)建過程,以及如何通過new操作符將構(gòu)造函數(shù)實例化,文章還通過代碼示例展示了new操作符的執(zhí)行流程,并強調(diào)了new操作符的返回規(guī)則和手動實現(xiàn)的方法

new 是 JavaScript 中創(chuàng)建實例對象的核心操作符,它不是簡單的語法糖,而是一套內(nèi)存分配、原型綁定、構(gòu)造函數(shù)執(zhí)行、返回值處理的完整流程。

我會用最通俗的語言 + 分步拆解 + 內(nèi)存/原型/原型鏈變化,把整個過程講透,你看完就能徹底理解。

一、先明確基礎(chǔ)概念(必須懂)

  1. 構(gòu)造函數(shù):普通函數(shù),首字母大寫(約定),用來生成實例(如 function Person(){}
  2. 原型 prototype每個函數(shù)都有的屬性,是一個對象,存放實例共享的方法/屬性
  3. __proto__每個對象都有的隱式原型,指向構(gòu)造函數(shù)的 prototype,是原型鏈的核心
  4. 原型鏈:實例通過 __proto__ 逐級向上查找屬性/方法的鏈條,終點是 Object.prototype,再向上是 null

二、new 操作符 4 步核心執(zhí)行流程

當(dāng)執(zhí)行 const obj = new 構(gòu)造函數(shù)() 時,JS 引擎會嚴(yán)格按 4 步執(zhí)行,每一步都會改變內(nèi)存原型關(guān)系

第 1 步:創(chuàng)建一個全新的空對象

// 內(nèi)部執(zhí)行:創(chuàng)建空對象,分配獨立堆內(nèi)存
const newObj = {}; 
  • 內(nèi)存變化:在堆內(nèi)存中開辟一塊新空間,存儲這個空對象,棧內(nèi)存的變量指向這塊堆地址
  • 原型/原型鏈:此時空對象的 __proto__ 默認(rèn)指向 Object.prototype(原生默認(rèn)規(guī)則)

第 2 步:綁定原型鏈(最核心步驟)

將新對象的隱式原型 __proto__ 指向構(gòu)造函數(shù)的顯式原型 prototype

// 內(nèi)部執(zhí)行:改寫原型指向
newObj.__proto__ = 構(gòu)造函數(shù).prototype; 

關(guān)鍵變化:

  1. 原型關(guān)系實例.__proto__ === 構(gòu)造函數(shù).prototype
  2. 原型鏈:新對象不再直接繼承 Object,而是繼承構(gòu)造函數(shù)的原型,原型鏈被重新串聯(lián)
  3. 內(nèi)存:只是修改引用地址,不新增內(nèi)存(__proto__ 是指針,指向堆中的原型對象)

第 3 步:執(zhí)行構(gòu)造函數(shù),綁定 this

把構(gòu)造函數(shù)的 this 強制綁定到第 1 步創(chuàng)建的新對象上,并執(zhí)行構(gòu)造函數(shù)內(nèi)部代碼

// 內(nèi)部執(zhí)行:call 改變 this 指向
構(gòu)造函數(shù).call(newObj); 

關(guān)鍵變化:

  1. this 指向:構(gòu)造函數(shù)內(nèi)的 this 不再指向 window/undefined,指向新對象
  2. 內(nèi)存:構(gòu)造函數(shù)內(nèi)的 this.xxx 賦值,會直接寫入新對象的堆內(nèi)存
  3. 屬性區(qū)分
    • 實例自身屬性:this.name → 存在實例對象內(nèi)存中
    • 共享屬性:構(gòu)造函數(shù).prototype.say → 存在原型對象中

第 4 步:返回實例對象

  • 如果構(gòu)造函數(shù)沒有手動返回對象,JS 自動返回第 1 步創(chuàng)建的新對象
  • 如果構(gòu)造函數(shù)手動返回了對象,則以手動返回的對象為準(zhǔn)(基本類型無效,仍返回新對象)
// 最終賦值
const obj = newObj; 

三、完整代碼演示 + 內(nèi)存/原型/原型鏈實時變化

我們用一個實際例子,一步步看所有變化:

// 1. 定義構(gòu)造函數(shù)(函數(shù)也是對象,有 prototype 屬性)
function Person(name) {
  // 構(gòu)造函數(shù)內(nèi)部:this 指向 new 創(chuàng)建的新對象
  this.name = name; // 實例自身屬性
}

// 2. 給構(gòu)造函數(shù)的原型添加方法(所有實例共享)
Person.prototype.say = function () {
  console.log("我是" + this.name);
};

// 3. 執(zhí)行 new 操作符
const p1 = new Person("張三");

執(zhí)行new Person("張三")全過程拆解

1. 創(chuàng)建空對象

堆內(nèi)存生成空對象:{},棧變量 p1 暫存引用

2. 綁定原型(核心)

p1.__proto__ = Person.prototype;

? 原型關(guān)系成立p1.__proto__ === Person.prototype

3. 執(zhí)行構(gòu)造函數(shù),this 綁定

Person.call(p1, "張三");
// 等價于執(zhí)行:p1.name = "張三"
  • 內(nèi)存:空對象變成 { name: "張三" }
  • this:完全指向 p1

4. 返回對象

p1 最終指向這個帶屬性的對象

四、內(nèi)存分布可視化(最關(guān)鍵?。?/h2>

棧內(nèi)存(存引用地址)

p1        → 堆內(nèi)存地址:0x100
Person    → 堆內(nèi)存地址:0x200

堆內(nèi)存(存實際對象)

# 0x100:p1 實例對象(自身屬性)
{
  name: "張三",
  __proto__: 0x300  // 指向 Person.prototype
}

# 0x200:Person 構(gòu)造函數(shù)對象
{
  prototype: 0x300, // 顯式原型
  __proto__: Function.prototype
}

# 0x300:Person.prototype 原型對象
{
  say: function(){},
  __proto__: Object.prototype, // 原型鏈向上
  constructor: Person
}

# 0x400:Object.prototype 原型鏈終點
{
  toString: ...,
  __proto__: null
}

五、原型鏈完整鏈條(一眼看懂)

執(zhí)行 new 后,p1 的原型鏈?zhǔn)牵?/p>

p1 → Person.prototype → Object.prototype → null

驗證代碼(直接復(fù)制運行)

console.log(p1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null(原型鏈終點)

屬性查找規(guī)則(原型鏈的作用)

  1. p1.name → 先查實例自身內(nèi)存 → 找到
  2. p1.say → 實例自身沒有 → 沿 __proto__Person.prototype → 找到
  3. p1.toString → 自身沒有 → 查 Person.prototype 沒有 → 查 Object.prototype → 找到

六、特殊情況:構(gòu)造函數(shù)有 return 時的變化

new 第四步的返回規(guī)則:

  1. return 基本類型(數(shù)字/字符串/布爾/null/undefined)→ 無效,仍返回新對象
  2. return 對象({} / [] / 實例)→ 生效,覆蓋 new 創(chuàng)建的對象,原型鏈?zhǔn)?/strong>

示例:

function Person() {
  this.name = "張三";
  return { age: 18 }; // 返回對象
}
const p1 = new Person();
console.log(p1); // { age: 18 } (不是 Person 實例,原型鏈斷裂)

七、手動實現(xiàn) new 操作符(徹底吃透原理)

我們用代碼還原 new 的 4 步邏輯,看完你會 100% 理解:

function myNew(constructor, ...args) {
  // 1. 創(chuàng)建空對象
  const obj = {};
  // 2. 綁定原型:obj.__proto__ = 構(gòu)造函數(shù).prototype
  Object.setPrototypeOf(obj, constructor.prototype);
  // 3. 執(zhí)行構(gòu)造函數(shù),綁定 this
  const res = constructor.apply(obj, args);
  // 4. 返回:如果構(gòu)造函數(shù)返回對象則用它,否則返回 obj
  return res instanceof Object ? res : obj;
}

// 測試
const p2 = myNew(Person, "李四");
p2.say(); // 我是李四
console.log(p2.__proto__ === Person.prototype); // true

總結(jié)(核心記憶點)

  1. new 4 步:創(chuàng)建空對象 → 綁定原型 → 綁定 this 執(zhí)行構(gòu)造函數(shù) → 返回對象
  2. 原型核心等式實例.__proto__ === 構(gòu)造函數(shù).prototype
  3. 內(nèi)存:實例存自身屬性,原型存共享屬性,節(jié)省內(nèi)存
  4. 原型鏈:實例 → 構(gòu)造函數(shù)原型 → Object原型 → null
  5. return:返回對象會覆蓋 new 創(chuàng)建的實例,基本類型無效

這就是 new 操作符內(nèi)存、原型、原型鏈的全部底層邏輯,也是 JS 面向?qū)ο蟮暮诵幕?/p>

以上就是JS中new操作符的完整執(zhí)行過程的詳細(xì)內(nèi)容,更多關(guān)于JS new操作符執(zhí)行過程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

登封市| 江城| 湄潭县| 平乡县| 嘉黎县| 浮梁县| 枝江市| 全南县| 保德县| 龙陵县| 霍城县| 顺昌县| 孟州市| 荥阳市| 大城县| 临安市| 德昌县| 湘阴县| 桐城市| 肃南| 武清区| 大洼县| 盘锦市| 永定县| 隆化县| 清水县| 西平县| 湖南省| 汤阴县| 嘉荫县| 田林县| 瑞昌市| 郸城县| 华亭县| 云梦县| 师宗县| 大安市| 安徽省| 凭祥市| 安义县| 梅河口市|