深入理解new運算符

来源:https://www.cnblogs.com/jofun/archive/2020/04/19/12731473.html
-Advertisement-
Play Games

在 JavaScript 中,new 運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。創建一個對象很簡單,為什麼我們還要多此一舉使用 new 運算符呢?它到底有什麼樣的魔力? ...


在 JavaScript 中,new 運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。創建一個對象很簡單,為什麼我們還要多此一舉使用 new 運算符呢?它到底有什麼樣的魔力?

認識 new 運算符

通過下麵的例子理解 new 運算符:

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

Person.prototype.getName = function () {
  console.log(this.name)
}

var joe = new Person('joe')

joe.sayHello = function () {
  console.log('Hello!')
}

joe.getName() // joe
joe.sayHello() // Hello!

Person.sayHello() // Uncaught TypeError: Person.sayHello is not a function

Person 是一個普通的函數,當它與 new 運算符一起使用時,Person 就是一個構造函數。通過 new Person('joe') 得到的新對象 joe 繼承了 Person 的屬性,同時,this 也指向 joe 實例。為 joe 添加的屬性 sayHello 不會影響 Person,即 joe 是區別與 Person 的一個新對象。

因此,通過 new 創建的實例對象和構造函數之間建立了一條原型鏈,並通過原型鏈賦予實例對象繼承屬性的能力

new 的原理和實現

通過上面的分析,new 運算符內部做瞭如下四個操作:

  • 創建一個空的簡單 JavaScript 對象(即{});
  • 鏈接新對象(即設置該新對象的構造函數)到函數對象;
  • 將新創建的對象作為 this 的上下文;
  • 如果該函數沒有返回對象,返回新創建的對象。

new 的實現如下:

function newOperator (ctor, ...args) {
  var obj = {};
  obj.__proto__ = ctor.prototype
  var res = ctor.apply(obj, args)
  return res || obj;
}

優化一下代碼:

function newOperator (ctor, ...args) {
  var o = Object.create(ctor.prototype) // 合併第一和第二步:創建一個空的簡單 JavaScript 對象(即{}),鏈接新對象(即設置該新對象的構造函數)到函數對象
  return fn.apply(o, args) || o
}

使用 newOperator 函數測試上面 Person 的例子:

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

Person.prototype.getName = function () {
  console.log(this.name)
}

var joe = newOperator(Person, 'joe')

joe.sayHello = function () {
  console.log('Hello!')
}

joe.getName() // joe
joe.sayHello() // Hello!

Person.sayHello() // Uncaught TypeError: Person.sayHello is not a function

結果是一致的。

更好的檢查方式是:

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

console.log(new Person('joe')) // @1
console.log(newOperator(Person, 'joe')) // @2

@1 和 @2 在控制台的顯示信息是一模一樣的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在日常開發中,我們可能會遇到將一個數組中裡面的重覆值去除,那麼,我就將我自己所學習到的幾種方法分享出來 去除數組重覆值方法: 1,利用indexOf()方法去除 思路:創建一個新數組,然後迴圈要去重的數組,然後用新數組去找要去重數組的值,如果找不到則使用.push添加到新數組,最後把新數組返回回去就 ...
  • 選項卡是前端常見的基本功能,它是用多個標簽頁來區分不同內容,通過選擇標簽快速切換內容。學習本教程之前,讀者需要具備html和css技能,同時需要有簡單的javascript基礎。 先來完成html部分。首先,需要一個元素把整個選項卡包含在內。新建一個div元素,它的id命名為tabBox,如下所示: ...
  • 作用域和閉包-執行上下文: 變數提升(寫代碼時千萬不要先使用再定義) <script> console.log(a);//undefined var a=10; fn('cyy',18); function fn(name,age){ age=20; console.log(name,age);// ...
  • 在前端面試時,面試官經常會問:瀏覽器是多進程還是單進程? 瀏覽器是多進程的,瀏覽器每一個 tab 標簽都代表一個獨立的進程(也不一定,因為多個空白 tab 標簽會合併成一個進程),瀏覽器內核(瀏覽器渲染進程)屬於瀏覽器多進程中的一種。 瀏覽器每個進程有多個線程,主要有以下線程 1)GUI 渲染線程: ...
  • VSCode卸載後進行重新安裝,發現新安裝的還有原來的一些配置,卸載的不徹底,有時候也容易出問題,可按照如下方法卸載乾凈: 1.進入控制面板卸載VSCode,也可以在VSCode的安裝目錄下用程式自帶的卸載程式(這個沒有親自試過.....) 2.這樣卸載完後還有一些配置文件,要想完全卸載,還需要將一 ...
  • 一、承接連載4 3.null和undefined沒有toString()方法,調用就會報錯 var num1 = undefined; console.log(num1.toString()); ​ var num2 = null; console.log(num2.toString()); 二、S ...
  • 定時器功能分析 核心思路: 定義一個變數,根據定時器,每秒執行一次,每次執行++自增操作 變數存儲的數值,就會每秒+1 現在需要的記錄效果,是每0.01秒,也就是10毫秒執行一次 根據累計的數值,執行進位 ms 如果達到 100,就是1秒 如果 秒 達到 60 就是 1分鐘 如果 分鐘 達到 60  ...
  • JavaScript與函數式編程 絕大多數編程語言都會有函數的概念(或者說所有的?我不太確定),他們都可以做出類似的操作: 但是Javascript更適合函數式編程,因為函數對於js來說,是 一等公民 。 我們可以把匿名函數賦值給一個變數,比如: 然後我們可以將這個函數賦值給另一個變數: 這樣做和直 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...