補環境基礎(一) 原型與原型鏈

1.創建對象的幾種方式

1.對象字面量模式

直接使用{}定義鍵值對:

const obj = { key: 'value' };  

2.Object()構造函數模式

使用內置構造函數(較少使用):

const person = new Object();
console.log(person)//輸出 {}

3.構造函數模式

通過函數模擬類,結合new關鍵字創建實例:

function Person(name) { this.name = name; }  
const person = new Person('John');  
console.log(person)//輸出{name:"join"}

2.原型與原型鏈

1.構造函數

實例有一個屬性constructor指向構造函數,實例擁有構造函數內部定義的屬性和方法,構造函數相當于一個模板藍圖

function User(){this.age = 18this.login = function (){console.log("登錄成功")}
}
user1 = new User()
user1 = new User()
console.log(user1.age) //18
console.log(user1.constructor == user2.constructor) //true

2.顯式原型

在js中,函數對象有一個特殊的屬性叫做顯式原型(prototype),它指向另一個對象,這個對象(User.prototype)被稱為原型對象

原型對象是用來共享屬性和方法

我們可以看下面的代碼

  • 在構造函數內部定義方法
function User(){this.age = 18this.login = function (){console.log("登錄成功")}
}
user1 = new User()
user2 = new User()
console.log(user1)// { age: 18, login: [Function (anonymous)] }
console.log(user1.age == user2.age) //true  
console.log(user1.login == user2.login) //false 因為指向了不同內存地址

每個實例在堆內存中都有自己獨立的方法。上面代碼中,創建2個實例就會創建2個login方法。

  • 在原型上定義方法
function User(){this.age = 18}
User.prototype.login = function(){ console.log("登錄成功")}
user1 = new User()
user2 = new User()
console.log(user1)//{ age: 18 }
console.log(user1.login == user2.login)//true
console.log(user1.login())//登錄成功

創建出來的實例對象上本身并沒有login方法

這個login方法在內存中只存在一份,它被分配在堆內存中,并且掛載到User.prototype這個對象上,如果在當前對象中沒有獲取到就會去它的原型上面獲取。

  • 二者比較
特性定義在原型上 User.prototype.login= function()定義在構造函數內部 this.login = function()
方法存儲位置原型對象(僅存一份)每個實例獨立存儲(每次new都創建新函數)
內存占用? 極低 (1000個實例共享1個方法)? 爆炸式增長 (1000個實例創建1000個獨立方法)

3.隱式原型

在js中,每個對象(除Object.create(null) 創建外)都有一個__proto__屬性(左右兩個短下劃線),這個被稱為隱式原型,

隱式原型是js中所有對象的核心繼承機制,直接決定了原型鏈的運作方式,__proto__存在的意義在于為原型鏈查找提供方向。隱式原型指向該對象的構造函數原型對象(即User.prototype)但通過 Object.create() 創建的對象會直接指向參數對象

1.通過構造函數創建的實例對象,實例對象的隱式原型指向構造函數的顯式原型

function User(){this.age = 18}
User.prototype.login = function(){ console.log("登錄成功")}
user1 = new User()
console.log(user.__proto__ == User.prototype)//true

2.通過Object.create()創建的實例對象,隱式原型指向參數對象

const animal = { type: 'unknown' };
// 參數對象 = animal
const dog = Object.create(animal); 
// dog.__proto__ 直接指向 animal(而非默認的 Object.prototype)
console.log(dog.type);            // 'unknown' ?
console.log(dog.__proto__ === animal); // true ?
  • 通過手動設置的原型實現繼承

我們知道,從一個對象上獲取屬性,如果在當前對象中沒有獲取到就會去它的原型上面獲取:

//user1.__proto__ = User.prototype  
var obj1 = {age:"18"}
var obj = {name:"john"};
obj.__proto__ = obj1
console.log(obj.name)//john
console.log(obj.age)//"18"

構造函數 、實例、原型對象之間的關系圖

在這里插入圖片描述

4.原型鏈

原型鏈(Prototype Chain)是JavaScript中實現繼承的機制。

每個對象都有一個原型(__proto__屬性),而原型本身也是一個對象,它也有自己的原型,這樣一層一層形成的鏈式結構就是原型鏈。當訪問一個對象的屬性或方法時,如果對象自身沒有該屬性,就會沿著原型鏈向上查找,直到找到該屬性或到達原型鏈的頂端(null)為止。

function Person() {}
const p = new Person();// 原型鏈驗證
console.log(p.__proto__ == Person.prototype); // L1 true
console.log(Person.prototype.__proto__ == Object.prototype);// L2 true
console.log(Object.prototype.__proto__ == null); // L3  true

原型繼承關系圖

注:圖中涉及到的部分知識點文中未提及

3.結語

本文旨在簡單的理解原型和原型鏈來對抗環境檢測還原關鍵加密邏輯,實際場景中網站會通過檢測原生對象原型鏈來判斷是否處于瀏覽器環境。

比如某網站會檢查navigator.plugins的原型鏈長度判斷是否爬蟲;

用自定義Error對象,捕獲錯誤后檢查stack屬性是否包含原生Error原型的方法名等等;

如需進一步理解原型鏈可參考文章:
參考文章

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

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

相關文章

Qt+yolov8目標識別

這是一個基于ONNX Runtime的YOLOv8目標檢測項目,支持CPU和GPU加速,使用Qt框架構建圖形化界面。攝像頭實時畫面識別視頻文件識別,能正常識別目標:紅綠燈,人,公交,巴士,摩托車 等YOLOv…

NLP分詞notes

BPE 貪心提取所有出現頻率高的成為詞。 BPE的訓練流程 1.初始化:將所有單個字符作為初始詞匯表的元素。 2.迭代合并: 統計語料中所有相鄰符號對(包括字符和合并后的符號)的出現頻率。找到出現頻率最高的符號對,將其合并…

【數據結構】棧和隊列-----數據結構中的雙生花

文章目錄[toc]棧與隊列:數據結構中的雙生花1. 棧:后進先出的有序世界1.1 概念及結構剖析1.2 實現方式深度解析數組 vs 鏈表實現1.3 動態棧實現詳解(附程序源碼)1.定義一個動態棧2.初始化3.銷毀4.入棧5.出棧6.取棧頂數據7.判空8.獲…

Mybatis-2快速入門

學習主線 必學必會屬于優化的東西。 快速入門需求說明 要求:開發一個MyBatis項目,通過MyBatis的方式可以完成對monster表的crud操作 1.創建mybatis數據庫-monster表 主鍵Primary Key默認非空Not null,就省略了 create database mybatis us…

Web基礎 -java操作數據庫

一、JDBCJDBC&#xff1a;&#xff08;Java DataBase Connectivity&#xff09;&#xff0c;就是使用Java語言操作關系型數據庫的一套API。為了使用JDBC操作數據庫&#xff0c;首先&#xff0c;我們需要在pom.xml文件中引入依賴<dependencies><!-- MySQL JDBC driver …

cell2location復現

https://github.com/BayraktarLab/cell2location/issues/348 根據你已下載的本地 wheel 文件&#xff0c;可以通過以下方式修改安裝命令&#xff0c;優先從本地路徑安裝 jaxlib&#xff0c;同時保持其他依賴的安裝方式不變&#xff1a; 解決方案 # 安裝 jax (從遠程 PyPI 源) p…

什么是 npm、Yarn、pnpm? 有什么區別? 分別適應什么場景?

什么是 npm、Yarn、pnpm? 有什么區別? 分別適應什么場景? 在前端開發中&#xff0c;包管理工具扮演著非常重要的角色。它們幫助開發者高效地管理項目的依賴&#xff0c;確保項目中所需的所有第三方庫和工具都能按時安裝&#xff0c;并且兼容版本。npm、Yarn 和 pnpm 是三款…

深度隱匿源IP:高防+群聯AI云防護防繞過實戰

隱蔽性挑戰 黑客常通過以下手段繞過基礎防護&#xff1a; HTTPS證書嗅探&#xff1a;訪問 https://源站IP&#xff0c;通過證書域名匹配暴露真實IP歷史解析記錄追蹤&#xff1a;從DNS數據庫獲取舊A記錄CDN緩存滲透&#xff1a;利用邊緣節點回源漏洞定位源站 三重防護方案 高防I…

如何加快golang編譯速度

跟著我的步驟來&#xff1a;第一步&#xff1a;(點擊edit)第二步&#xff1a;將go tool arguments設置為-p4&#xff0c;初始值設為4&#xff0c; 代表最多同時編譯4個包&#xff08;非文件&#xff09;。電腦性能好時&#xff0c;可設為CPU最大核心數&#xff08;充分利用多核…

瀏覽器自動化方案

B端后臺列表頁自動新增素材方案 我設計了一套完整的瀏覽器自動化方案&#xff0c;使用 Puppeteer 實現B端后臺列表頁的自動新增素材功能。該方案包含數據組織、瀏覽器操作、錯誤處理等完整流程。 一、技術選型 瀏覽器自動化工具&#xff1a;Puppeteer (https://pptr.dev)任務調…

MPPT電路設計

反激的具體計算過程要寫好起碼要一天&#xff0c;所以本次先更MPPT。這章不計算具體參數&#xff0c;只做分析。 目錄 一、電路作用 二、電路設計 采樣電路和輸入電路 主體電路 驅動電路 一、電路作用 MPPT電路是一種廣泛應用于光伏發電、風力發電等新能源系統中的關鍵電…

【基于飛漿訓練車牌識別模型】

基于飛漿訓練車牌識別模型 基于飛漿訓練車牌識別模型 LPRNet&#xff08;License Plate Recognition via Deep Neural Networks&#xff09;是一種輕量級卷積神經網絡&#xff0c;專為端到端車牌識別設計&#xff0c;由Intel IOTG Computer Vision Group的Sergey Zherzdev于201…

No module named ‘sklearn‘

1、運行python數據分析庫時報錯 No module named sklearn2、原因 虛擬環境未安裝 sklearn 庫&#xff08;即 scikit-learn&#xff09;。 3、解決方案 pip install scikit-learn使用國內鏡像源&#xff1a; pip install scikit-learn -i https://mirrors.aliyun.com/pypi/simpl…

XPath注入攻擊詳解:原理、危害與防御

什么是XPath注入&#xff1f; XPath注入&#xff08;XPath Injection&#xff09;是一種針對使用XPath查詢語言的應用程序的安全攻擊技術&#xff0c;類似于SQL注入。當應用程序使用用戶提供的輸入來構造XPath查詢而沒有進行適當的過濾或轉義時&#xff0c;攻擊者可以通過構造惡…

網絡編程(套接字)

目錄 一、套接字 1、套接字的作用 2、關于TCP和UDP協議 1. TCP協議 2. UDP協議 3. 兩者的區別 2、套接字函數 1&#xff09;函數 socket&#xff08;創建套接字同文件描述符&#xff09; 2&#xff09;準備套接字用結構體 1. 套接字的結構體 2. 客戶端的套接字&…

R語言安裝包

# 在安裝過程中指定源地址 install.packages("RCurl", repos "https://mirrors.tuna.tsinghua.edu.cn/CRAN/") # 查看當前鏡像 options()$repos # 設置為中科大鏡像 options("repos" c(CRAN"https://mirrors.ustc.edu.cn/CRAN/")…

微服務引擎 MSE 及云原生 API 網關 2025 年 5 月產品動態

點擊此處&#xff0c;了解微服務引擎 MSE 產品詳情。

性能測試過程中監控linux服務器資源情況

文章目錄1. cpu使用情況&#xff08;1&#xff09;性能瓶頸類型CPU密集型瓶頸??I/O或等待瓶頸?&#xff08;2&#xff09;資源分配與競爭?資源爭用分析?虛擬化環境資源分配?&#xff08;3&#xff09;系統穩定性與異常??異常波動與毛刺??過熱降頻影響?&#xff08;4…

使用defineExpose暴露子組件的屬性和方法、頁面生命周期onLoad和onReady的使用

歡迎來到我的UniApp技術專欄&#xff01;&#x1f389; 在這里&#xff0c;我將與大家分享關于UniApp開發的實用技巧、最佳實踐和項目經驗。 專欄特色&#xff1a; &#x1f4f1; 跨平臺開發一站式解決方案 &#x1f680; 從入門到精通的完整學習路徑 &#x1f4a1; 實戰項目經…

新手必看!VSCodePyCharm 配置 OpenCV 超詳細教程(支持 Python 和 C++ 雙語言)

新手必看&#xff01;VSCode&PyCharm 配置 OpenCV 超詳細教程&#xff08;支持 Python 和 C 雙語言&#xff09; 適用對象&#xff1a;初學者&#xff0c;希望在 VSCode 與 PyCharm 兩款常用 IDE 中&#xff0c;學會配置并使用 OpenCV&#xff0c;分別實現 Python 與 C 環境…