JavaScript定義函數,創建函數實例時的內部原理

1、定義一個函數,JavaScript內部各做了哪些事情

定義一個函數時,JavaScript內部執行了以下步驟:

  1. 解析函數聲明:
    當你定義一個函數時,JavaScript的解析器會首先解析函數聲明。這意味著它會檢查函數聲明的語法是否正確,包括函數名、參數列表、函數體等。

  2. 創建函數對象:
    一旦函數聲明被解析通過,JavaScript會在內存中創建一個函數對象。這個函數對象包含了函數的定義、參數信息、函數體以及其它與函數相關的元數據。

  3. 函數作用域和閉包:
    在函數創建的過程中,JavaScript會確定函數的作用域。這包括確定函數內部可以訪問的變量和函數。如果函數內部引用了外部作用域的變量,那么這些變量會被“封閉”在函數內部,形成閉包。閉包允許函數在執行完畢后依然能夠訪問其定義時的詞法環境。

  4. 將函數對象賦值給變量:
    如果你使用了變量來定義函數(例如 var myFunction = function() { ... };),那么JavaScript會將新創建的函數對象賦值給相應的變量。這樣,你就可以通過變量來引用和調用這個函數了。

  5. 函數原型和prototype屬性:
    每個函數對象都有一個prototype屬性,它指向一個原型對象。這個原型對象包含了可以被函數的所有實例共享的屬性和方法。當你使用new關鍵字創建函數的新實例時,新實例的內部[[Prototype]]鏈接會指向這個原型對象,從而可以訪問原型上的屬性和方法。

函數對象的原型對象(prototype)的默認值是一個空的Object對象。
換句話說,當你定義一個函數時,JavaScript會自動為其添加一個prototype屬性,這個屬性的默認值是一個空的對象(即不包含任何屬性和方法的對象)。這個原型對象主要用于實現基于原型的繼承和屬性查找。

在JavaScript中,每個構造函數都有一個prototype屬性,這個屬性是一個指針,指向一個對象,該對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。按照慣例,這個prototype對象會包含一個名為constructor的屬性,該屬性是一個指向prototype屬性所在函數的指針。這樣,構造函數就能夠識別哪些對象是其實例。

需要注意的是,雖然prototype對象的默認值是一個空對象,但你可以根據需要向其中添加屬性和方法,以便在構造函數的實例中共享這些屬性和方法。此外,你也可以通過修改prototype對象來修改已有實例的行為,但這通常是不推薦的,因為這可能會導致代碼難以理解和維護。

下面是一個簡單的例子,展示了如何查看一個函數對象的prototype屬性的默認值:

function MyFunction() {// 函數體
}console.log(MyFunction.prototype); // 輸出: {}

在這個例子中,MyFunction是一個空函數,我們打印出它的prototype屬性,可以看到它的默認值是一個空的Object對象。

  1. 函數屬性和方法:
    函數對象自身也有一些屬性和方法,例如name(函數名)、length(參數個數)、callapplybind等。這些屬性和方法允許你操作函數或獲取函數的元數據信息。

下面是一個簡單的函數定義示例:

function myFunction(arg1, arg2) {// 函數體console.log('Hello, world!');
}

在這個例子中,JavaScript會執行以下步驟:

  • 解析函數聲明myFunction,檢查其語法是否正確。
  • 創建一個新的函數對象,包含myFunction的定義、參數arg1arg2、函數體以及其它元數據。
  • 確定函數的作用域,并檢查是否有閉包形成。
  • 將這個函數對象賦值給變量myFunction
  • 為這個函數對象創建一個prototype屬性,并設置其默認的constructor屬性指向函數對象本身。

最終,你可以通過myFunction變量來調用這個函數,并執行其函數體中的代碼。

2、new 創建一個函數實例時,JavaScript內部做了哪些事情

當使用 new 關鍵字創建一個函數的實例時,JavaScript 內部執行以下步驟:

  1. 創建新對象
    JavaScript 首先會創建一個新的空對象。這個新對象將用作新創建的實例。

  2. 設置原型鏈
    新創建的對象的內部 [[Prototype]] 鏈接(這不是一個真正的屬性,而是一個內部鏈接)會被設置為構造函數的 prototype 對象。這意味著新創建的對象可以繼承構造函數原型上的屬性和方法。

  3. 構造函數調用
    接下來,構造函數會被調用,并將新創建的對象作為 this 上下文。這意味著在構造函數內部,你可以使用 this 關鍵字來訪問和修改新創建的對象。

  4. 執行構造函數體
    構造函數的代碼(函數體)會被執行。在這個過程中,你可以定義新對象的屬性、方法,以及執行其他任何初始化代碼。

  5. 返回新對象
    如果構造函數沒有顯式地返回一個非原始值(即非 nullundefined、數字、字符串或布爾值),那么 new 表達式的結果就是新創建的對象。如果構造函數返回了一個對象,那么這個返回的對象將替代新創建的對象,并作為 new 表達式的結果。

  6. 實例屬性和方法
    在構造函數中定義的任何屬性和方法都將成為新創建對象的實例屬性和方法。這些屬性和方法僅對當前實例可見,每個實例都會有自己的一套屬性和方法的副本。

下面是一個使用 new 關鍵字創建函數實例的示例:

function Person(name, age) {this.name = name;this.age = age;this.introduce = function() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);}
}var john = new Person('John', 30);
john.introduce(); // 輸出: Hello, my name is John and I am 30 years old.

在這個例子中:

  • Person 是一個構造函數。
  • 使用 new Person('John', 30) 創建了一個新的 Person 實例。
  • 新對象的 [[Prototype]] 鏈接被設置為 Person.prototype
  • 構造函數被調用,并設置了新對象的 nameage 屬性,以及 introduce 方法。
  • introduce 方法是定義在新對象上的實例方法,每個實例都會有自己的方法副本。
  • john 變量引用了新創建的 Person 實例,并可以調用其 introduce 方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718889.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718889.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718889.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[NSSCTF 2nd]MyJs

做一題ejs原型鏈污染 首先是登錄界面 源碼里面提示了源碼的路由 js不熟先審計一下 const express require(express); #導入Express框架,用于構建Web應用程序的服務器和路由 const bodyParser require(body-parser); #導入body-parser中間件,用于解析…

軟考證書=職稱證書?

官方的回答 根據《計算機技術與軟件專業技術資格(水平)考試暫行規定》(國人部發〔2003〕39號)規定,通過考試并獲得相應級別計算機專業技術資格(水平)證書的人員,表明其已具備從事相…

學習Android的第二十二天

目錄 Android ContextMenu 上下文菜單 ContextMenu 范例 參考文檔 Android SubMenu 子菜單 范例 參考文檔 Android PopupMenu 彈出菜單 范例 參考文檔 Android ContextMenu 上下文菜單 在Android開發中,ContextMenu(上下文菜單)為…

使用Javassist 在android運行時生成類

序言 最近在寫框架,有一個需求就是動態的生成一個類,然后查閱了相關文獻,發現在android中動態生成一個類還挺麻煩。因次把一些內容分享出來,幫助大家少走彎路。 方案一 DexMaker DexMaker 是一個針對 Android 平臺的庫&#xf…

Myqsort:基于冒泡排序算法的C語言實現

我們將詳細介紹一個基于冒泡排序算法的自定義排序函數——Mysqrt。該函數通過使用用戶提供的比較函數進行元素間的比較&#xff0c;并結合swap交換函數對任意類型的數據進行排序。下面是對代碼的逐行解析。 邏輯導圖 代碼實現 // 頭文件 #include<stdio.h>// 定義比較函…

華為自動駕駛技術詳解報告分享

ADS2.0首發搭載問界M5智駕版&#xff0c;城市NCA計劃年底全國開通。2023年4月16日華為在智能汽車解決方案發布會上發布了最新的ADS2.0產品&#xff0c;硬件數量減少至27個(11個攝像頭12個超聲波雷達3個毫米波雷達1個激光雷達,ADS1.0有34個)&#xff0c;車載計算平臺改為MDC610&…

python自學2

第一階段第三章 if&#xff0c;elif&#xff0c;else語句 這個是有順序的&#xff0c;如果第一個滿足下面的就不會執行&#xff0c;else也可以不寫&#xff0c;執行的效果等同于三個獨立的if。 還可以寫的更加簡潔一些 直接輸入的參數帶入到判斷里面去 小練習&#xff1a; 做…

打造專屬投屏體驗:Windows系統投屏到iOS系統

想要將電腦投屏共享給同事或朋友&#xff0c;又擔心隱私內容泄露&#xff1f;來來來&#xff0c;這里有妙招&#xff01; AirDroid Cast網頁版讓電腦投屏變得挑剔&#xff0c;只展示你允許共享的內容。會議資料、個人照片、敏感文件&#xff0c;都將得到嚴格的篩選&#xff0c;…

云原生之容器編排實踐-ruoyi-cloud項目部署到K8S:Nacosv2.2.3

背景 前面搭建好了 Kubernetes 集群與私有鏡像倉庫&#xff0c;終于要進入服務編排的實踐環節了。本系列拿 ruoyi-cloud 項目進行練手&#xff0c;按照 MySQL &#xff0c; Nacos &#xff0c; Redis &#xff0c; Nginx &#xff0c; Gateway &#xff0c; Auth &#xff0c;…

傳輸層Transport layer (ISO15118-20:2022) (7.7 part1) -- TCPUDP

7.7 Transport layer 這段描述闡明了文檔中子條款及其所有子條款的特定要求,這些要求分別適用于私有SECC(Supply Equipment Communication Controller)和公共SECC。除非在特定子條款或其內部的任何子條款中另有說明,否則不應將私有SECC和公共SECC視為可互換的。 這意味著…

問題解決 | RuntimeError: CUDA error: invalid device ordinalCUDA kernel errors

錯誤&#xff1a; RuntimeError: CUDA error: invalid device ordinal CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect. For debugging consider passing CUDA_LAUNCH_BLOCKING1. Compile with TO…

windows環境下Grafana+loki+promtail入門級部署日志系統,收集Springboot(Slf4j+logback)項目日志

&#x1f339;作者主頁&#xff1a;青花鎖 &#x1f339;簡介&#xff1a;Java領域優質創作者&#x1f3c6;、Java微服務架構公號作者&#x1f604; &#x1f339;簡歷模板、學習資料、面試題庫、技術互助 &#x1f339;文末獲取聯系方式 &#x1f4dd; 往期熱門專欄回顧 專欄…

動態規劃DP之背包問題4---分組背包問題

目錄 DP分析&#xff1a; 例題&#xff1a; 01背包&#xff1a; 一種物品只有一件 動態規劃DP之背包問題1---01背包問題-CSDN博客 完全背包&#xff1a;一種物品有無限件 動態規劃DP之背包問題2---完全背包問題-CSDN博客 多重背包&#xff1a;一種物品有有限…

【三維重建】【SLAM】SplaTAM:基于3D高斯的密集RGB-D SLAM(CVPR 2024)

題目&#xff1a;SplaTAM: Splat, Track & Map 3D Gaussians for Dense RGB-D SLAM 地址&#xff1a;spla-tam.github.io 機構&#xff1a;CMU&#xff08;卡內基梅隆大學&#xff09;、MIT&#xff08;美國麻省理工&#xff09; 總結&#xff1a;SplaTAM&#xff0c;一個新…

十個勤天生菜原價4.9元被炒到300元,2024新商機!新興創業項目!

近日&#xff0c;一則關于生菜價格暴漲的新聞引起了廣泛關注。原價4.9元的生菜&#xff0c;在短短時間內被炒至300元&#xff0c;令人咋舌。在這背后&#xff0c;除了市場供需失衡、炒作等因素外&#xff0c;我們不禁思考&#xff1a;這樣的現象背后是否隱藏著更大的商機&#…

怎么更改淘寶開店時間

更改淘寶開店時間的注意事項與建議 在淘寶上開店&#xff0c;對于許多賣家來說&#xff0c;選擇合適的開店時間是非常重要的。本文將為您介紹如何更改淘寶開店時間&#xff0c;以及在更改過程中需要注意的事項和建議。 一、如何更改淘寶開店時間 在淘寶上更改開店時間相對簡…

LaTeX插入圖片占位符

關于插入圖片更多說明&#xff08;多圖并排、子標題設置等&#xff09;可參考鏈接 LaTeX插入圖片 插入圖片占位符 參考鏈接&#xff1a;https://blog.csdn.net/yq_forever/article/details/129431799 在論文草稿階段有的時候想先插入圖片占位符擬定大綱或寫作思路&#xff0…

張宇30講學習筆記

初等數學 x \sqrt{x} x ?是算數平方根&#xff0c;一定≥0&#xff1b; x 2 \sqrt{x^2} x2 ?|x| x2|x2||x|2 x3≠|x3||x|3 不等式 a>0&#xff0c;b>0&#xff0c;則ab≥2 a b \sqrt{ab} ab ? 對數 ln a b \frac{a}{b} ba?lna-lnb 高等數學 單調性 線性代數

Linux CentOS使用Docker部署Apache Superset并實現遠程分析數據

文章目錄 前言1. 使用Docker部署Apache Superset1.1 第一步安裝docker 、docker compose1.2 克隆superset代碼到本地并使用docker compose啟動 2. 安裝cpolar內網穿透&#xff0c;實現公網訪問3. 設置固定連接公網地址 前言 Superset是一款由中國知名科技公司開源的“現代化的…

WordPress排除調用某個分類下的文章

wordpress在調用分類下文章時&#xff0c;有時需要排除調用某個分類的文章&#xff0c;下面的這段代碼&#xff0c;就可以輕松實現不調用特定ID的分類內容。 <?phpquery_posts("showposts10&cat-1"); //cat-1為排除ID為1的分類下文章while(have_posts()) : …