對象進階與擴展

目錄

創建對象

Object.create()

原型

原型操作

原型污染

對象屬性

屬性特征

?枚舉屬性

Object.keys()

Object.getOwnPropertyNames()

?Object.getOwnPropertyDescriptor()

Object.definePeoperty()

Object.definePeoperties()

訪問器屬性

getter和setter屬性

屬性訪問錯誤

檢測屬性

新增方法

Object.is

Object.assign


創建對象

Object.create()

使用Object.create()方法創建一個新對象

// obj1繼承了屬性x和y。
let obj1 = Object.create({ x: 1, y: 2 });
//obj2是一個普通的空對象。
let obj2 = Object.create(Object.prototype);
//obj3不繼承任何屬性和方法。
let obj3 = Object.create(null);

Object.create(新對象的原型,新對象的屬性描述符)

const animal = {eat() {console.log("Eating...");},
};
const dog = Object.create(animal, {name: { value: "Doggie" },bark: {value: function () {console.log("Barking...");},},
});
dog.eat();
dog.bark();
//輸出
//Eating...
//Barking...

原型

每一個JavaScript對象都和原型對象相關聯。(每一個對象都從原型繼承屬性。)

所有通過對象字面量創建的對象都具有同一個原型對象。

通過new和構造函數創建的對象的原型就是構造函數的prototype屬性引用的對象。

new Array()對象的原型就是Array.prototype,又繼承Object.prototype。

let obj = { value: 100 };
Object.prototype.flag = "head";
console.log(obj.flag);
let arr = [1, 2, 3, 4];
console.log(arr.flag);
//輸出
//head
//head

原型操作

Object.getPrototypeOf(對象):查詢對象的原型

Object.setPrototypeOf(對象,新的原型對象):為對象重新指定原型對象

obj1.isPrototypeOf(obj2):檢測對象obj2是否是對象obj1的原型(obj1是否在obj2的原型鏈上)

原型污染

修改JavaScript對象的原型鏈,從而影響所有基于該原型的對象行為。

防御措施:

使用Object.create(null)創建無原型對象;

避免使用__proto__,改用Object.getPrototypeOf()Object.setPrototypeOf()。

對象屬性

數據屬性:對象屬性可以是任意JavaScript值。

屬性特征

每個數據屬性之間還有一些與之相關的值。

  • 可寫:是否可以設置屬性值?
  • 可枚舉:是否可以通過for/in結構返回該屬性
  • 可配置:是否可以刪除或修改該屬性

?枚舉屬性

for/in循環可以在循環體中遍歷對象中所有可枚舉的屬性(包括自身屬性和繼承屬性)

let o = Object.create({ m: 10, n: 20 });
o.x = 1;
o.y = 2;
o.z = 3;
for (let p in o) {console.log(p, o[p]);
}
//輸出
//x 1
//y 2
//z 3
//m 10
//n 20
Object.keys()

返回一個數組。這個數組由對象中可枚舉的自有屬性的名稱組成。

let o = Object.create({ m: 10, n: 20 });
o.x = 1; o.y = 2; o.z = 3;
console.log(Object.keys(o));
//輸出
//[ 'x', 'y', 'z' ]
Object.getOwnPropertyNames()

返回對象的所有自有屬性的名稱

let o = Object.create({ m: 10, n: 20 });
o.x = 1;
o.y = 2;
o.z = 3;
console.log(Object.getOwnPropertyNames(o));
//輸出
//[ 'x', 'y', 'z' ]

?Object.getOwnPropertyDescriptor()

可以獲得某個對象特定屬性的屬性描述符。

console.log(Object.getOwnPropertyDescriptor(circle, "r"));
//{value: 9.549296585513721,writable: true,enumerable: true,configurable: true}

Object.definePeoperty()

傳入要修改的對象、要床架或修改的屬性的名稱以及屬性描述符對象。

  • 第一個參數:傳入要修改的對象
  • 第二個參數:要創建或修改的屬性的名稱
  • 第三個參數:屬性描述符對象
let o = {};
Object.defineProperty(o, "x", {value: 10,writable: true,enumerable: false,configurable: false,
});
console.log(o.x, Object.keys(o));//10 []

value(屬性值),writable(可寫性),enumerable(可枚舉性),configurable(可配置性)

傳入Object.defineProperty()的屬性描述符對象不必包含所有4個特性。

Object.definePeoperties()

同時修改或創建多個屬性。

  • 第一個參數:要修改的對象
  • 第二個參數:映射表(包含要新建或者修改的屬性名稱,以及屬性的描述)
let p = Object.defineProperties({},{x: { value: 1, writable: true, enumerable: true, configurable: true },y: { value: 1, writable: true, enumerable: true, configurable: true },r: {get: function () {return Math.hypot(this.x, this.y);},enumerable: true,configurable: true,},}
);
console.log(p);//{ x: 1, y: 1, r: [Getter] }

訪問器屬性

屬性可以是一個getter或setter函數。

可寫性是由setter方法是否存在決定的。

存取器屬性的4個特性是讀取(get)、寫入(set)、可枚舉性和可配置性。

getter和setter屬性

getter的返回值就是屬性存取表達式的值。

setter負責“設置”屬性值。

let circle = {r: 10,get round() {return 2 * this.r * Math.PI;},set round(v) {this.r = v / 2 / Math.PI;},get area() {return Math.PI * this.r ** 2;},
};
console.log(circle.round, circle.area);//62.83185307179586 314.1592653589793
circle.round = 60;
console.log(circle.r, circle.area);//9.549296585513721 286.47889756541167let circle1 = Object.create(circle);
circle1.r = 20;
console.log(circle1.round);//125.66370614359172
circle1.round = 500;
console.log(circle1.r, circle1.area);//79.57747154594767 19894.367886486918

和數據屬性一樣,存取器屬性是可以繼承的。

屬性訪問錯誤

查詢一個不存在的屬性并不會報錯,返回undefined。

如果對象不存在,查詢這個不存在的對象 的屬性就會報錯。

let one = {};
// let one = { two: { three: 3 } };
console.log(one.two.three);//報錯
if (one) {
if (one.two) {
if (one.two.three) console.log(one.two.three);
}
}
console.log(one && one.two && one.two.three);
console.log(one?.two?.three); // Null傳導運算符

檢測屬性

檢查屬性的方法:

  • in字符串
  • hasOwnPreperty()
  • properlylsEnumerable()
let o = { x: 1 };
console.log("x" in o);//true
console.log("y" in o);//false
console.log("toString" in o);//true
console.log(o.hasOwnProperty("x"));//true
console.log(o.hasOwnProperty("y"));//false
console.log(o.hasOwnProperty("toString"));//false
console.log(o.propertyIsEnumerable("x"));//true
console.log(o.propertyIsEnumerable("y"));//false
console.log(o.propertyIsEnumerable("toString"));//false
console.log(Object.prototype.propertyIsEnumerable("toString"));//false

Object.prototype 包含一個 toString 方法,所以即使對象 o 自身沒有定義 toString,in 操作符也會沿著原型鏈查找到 Object.prototype.toString。

新增方法

Object.is

比較兩個值是否相等,返回一個布爾值。

console.log(Object.is(1, 2)); // false
console.log(Object.is(1, "1"), 1 == "1", 1 === "1"); // false true false
console.log(Object.is(NaN, NaN), NaN == NaN, NaN === NaN); // false true false
console.log(Object.is(0, -0), 0 == -0, 0 === -0); // false true true
console.log(Object.is(+0, -0)); // false
console.log(Object.is(+0, 0)); // true

Object.assign

將所有可枚舉的自身屬性從一個或多個源對象復制到目標對象,返回目標對象。(對象的深層復制

const symbolTag = Symbol("is object");
const defaults = {color: "red",size: "10px",[symbolTag]: "configuration",
};
const options = {color: "blue",opacity: 0.5,
};
const merged = Object.assign({}, defaults, options);
console.log(defaults);
//{ color: 'red', size: '10px', [Symbol(is object)]: 'configuration' }
console.log(options);
//{ color: 'blue', opacity: 0.5 }
console.log(merged);
//{ color: 'blue', size: '10px', opacity: 0.5, [Symbol(is object)]: 'configuration' }

Object.assign()方法不會直接遞歸對象,如果對象的屬性值是一個對象,則會直接復制該對象的引用,而不會復制該對象的屬性。

const symbolTag = Symbol("is object");
const defaults = {color: "red",size: "10px",[symbolTag]: "configuration",
};
const options = {color: "blue",opacity: 0.5,
};
const merged = Object.assign({}, defaults, options);
const options2 = {color: "blue",opacity: 0.5,position: { x: 10, y: 20 },
};
const merged2 = Object.assign({}, defaults, options2);
console.log(merged2);
//{
//  color: 'blue',
//  size: '10px',
//  opacity: 0.5,
//  position: { x: 10, y: 20 },
//  [Symbol(is object)]: 'configuration'
//}
console.log(merged2.position === options2.position);
//true

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

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

相關文章

理解圖像的隨機噪聲

圖像灰度信息很難精確測量,一般情況下測量值總在真實值附近晃動,使用概率模型可以對該隨機性建模,大致如下: 1 概率密度函數 1)隨機變量 x 的概率密度函數 p(x) 定義為:當 趨近于 0 時,在區間 上…

華為云鏡像倉庫下載 selenium/standalone-chrome 鏡像

你可以使用以下步驟從華為云鏡像倉庫下載 selenium/standalone-chrome 鏡像&#xff1a; 1. 登錄華為云鏡像倉庫&#xff08;如果需要認證&#xff09; bash sudo docker login -u <用戶名> -p <密碼> swr.cn-north-4.myhuaweicloud.com 如果沒有華為云賬號&…

Push-T, AloHa, Rlbench三個仿真環境信息

1.Push-T 很好兄弟&#xff0c;你問得很關鍵&#xff1a;你給我的三段代碼其實是一套完整的推理錄像 pipeline&#xff0c;它們之間既有獨立功能&#xff0c;又有順序依賴關系。我來幫你分段解釋&#xff0c;每段是什么功能、三段之間怎么配合&#xff0c;讓你徹底搞明白。 &a…

Linux信號機制:從入門到精通

嘿&#xff0c;小伙伴們&#xff01;今天我要和大家聊一個Linux系統中非常有趣又重要的話題——信號機制。別擔心&#xff0c;雖然信號聽起來有點高深&#xff0c;但我會用最通俗易懂的語言&#xff0c;配合清晰的圖表&#xff0c;帶你徹底搞懂這個概念&#xff01; 什么是信號…

Vue3項目引入高德地圖【超詳細教程】

前言 在 Vue 3 項目中集成高德地圖&#xff08;AMap&#xff09;是一個常見的需求。本文將詳細介紹如何在 Vue 3 項目中使用高德地圖&#xff0c;包括安裝配置、基本使用以及一些進階功能的實現。 一、環境準備 1.1 vue3項目初始化 步驟 1&#xff1a;初始化項目 npm crea…

blender mcp安裝(完全免費的ai建模)

1.最關鍵的一步&#xff0c;建議最早執行(就是安裝uvx) mac系統執行 brew install uvwindows執行 powershell -c "irm https://astral.sh/uv/install.ps1 | iex" 出現這一步就成功安裝uvx了&#xff0c;因為mcp需要使用uvx 2.第二步驟 github地址: https://gith…

GIS開發入門教程與筆記分享

大家好&#xff0c;我是地信小學生&#xff0c;距離5月3日發布暫停更新以來&#xff0c;也一兩個月啦&#xff0c;這期間也陸陸續續更新了點內容。 我自己寫的筆記主要是以入門筆記為主&#xff0c;真正的內容并不多&#xff0c;包括&#xff1a;GIS基礎、PostgreSQLPostGIS入門…

設計模式-代理模式、裝飾者模式

代理模式 Proxy&#xff08;代理&#xff09;—對象結構型模式定義&#xff1a;給某一個對象提供一個代理對象&#xff0c;并由代理對象控制原有對象的引用。 代理模式的核心思想是&#xff1a;創建一個代理對象&#xff0c;代理對象在調用目標方法時&#xff0c;可以插入額外…

國產安路FPGA純verilog視頻圖像去霧,基于暗通道先驗算法實現,提供5套TD工程源碼和技術支持

目錄 1、前言工程概述免責聲明 2、相關方案推薦我已有的所有工程源碼總目錄----方便你快速找到自己喜歡的項目國產安路FPGA相關方案推薦本博主已有的圖像處理方案 3、設計思路框架工程設計原理框圖輸入Sensor之-->GC0308攝像頭輸入Sensor之-->OV7725攝像頭輸入Sensor之--…

Windows商店中的簡筆畫學習應用

此應用包含動物、植物、人物、交通工具、卡通等類別超過1500張線條圖片&#xff0c;支持圖片臨摹和圖片填色&#xff0c;可以將繪圖和填色結果保存成文件&#xff0c;也可以打開本地圖片進行臨摹和填色。 菜單說明 右側繪圖區上方菜單功能包括&#xff1a;打開文件&#xff1…

樹莓派4B --ubundu20.04 機載電腦配置WIFI熱點

不要用刷機過程配置WIFI賬號&#xff0c;因為在那里配置的WIFI都是不受控的&#xff0c;會出很多問題。 1.安裝網絡 sudo apt-get install network-manager 2.將源碼CLONE到本地 sudo git clone https://github.com/oblique/create_ap cd create_ap sudo make install 當你…

??JETSON NANO B01? 在AIOT 的領域的作用

低功耗邊緣設備的理想選擇 &#x1f449; ??適合人群??&#xff1a;精打細算、小廠搞智能監控的 ??Jetson Nano B01??&#xff08;4GB內存/0.47TOPS算力&#xff09;&#xff0c;JetBot (NVIDIA社區版) 機器人/自動駕駛項目? ??硬件??&#xff1a;Jetson Nano B0…

Kioptrix Level2

靶機截圖 收集信息 主機發現 打開靶機后&#xff0c;用kali探測靶機的 IP arp-scan-l 可以用nmap進行同網段掃描探測存活ip nmap -sP 10.4.7.0/24 端口掃描 命令過程 nmap -sT -sV -p- -O 10.4.7.220 -sT&#xff1a;TCP連接掃描 -sV&#xff1a;服務版本探測 -p-&#x…

Word之電子章制作——1

第一步&#xff1a;在插入 ——形狀哪里選擇一個圓形&#xff0c;并且下一步按住shift鍵拉出一個正圓形。 第二步&#xff1a;鼠標右鍵去掉背景顏色&#xff0c;邊框粗細設置成3磅。 第三步&#xff1a;在插入導航窗找到藝術字&#xff0c;點擊大寫的A&#xff0c;輸入公司名字…

LeetCode 2799.統計完全子數組的數目

給你一個由 正 整數組成的數組 nums 。 如果數組中的某個子數組滿足下述條件&#xff0c;則稱之為 完全子數組 &#xff1a; 子數組中 不同 元素的數目等于整個數組不同元素的數目。 返回數組中 完全子數組 的數目。 子數組 是數組中的一個連續非空序列。 示例 1&#xff1…

33.表復制和去重

1.表結構的復制(LIKE) 當我們想復制一個表的時候&#xff0c;首先需要創建一個與被復制表相同結構的表。這時候就要用到關鍵字like&#xff1a; 語法使用&#xff1a; create table table_name LIKE temp_table 示例&#xff1a;復制一個和表emp&#xff08;老朋友了&#…

GitLab 18.1 正式發布Maven 虛擬倉庫、密碼泄露檢測等功能,可升級體驗!

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

藍牙網絡拓撲面試通關:微微網與散射網原理 + 真題解析

為什么面試官總愛問藍牙拓撲? 你可能有過這樣的經歷:面試嵌入式 / 物聯網 / 無線通信崗位時,面試官突然問:“藍牙的微微網和散射網有什么區別?” 別慌!這不是在考你背定義,而是考察你對無線通信核心邏輯的理解 ——如何用有限資源實現高效組網。 藍牙作為短距離無線通信…

[Python]-基礎篇1- 從零開始的Python入門指南

無論你是尚未接觸編程的新手,還是想從其他語言轉向Python的開發者,這篇文章都是你的入門課。 一、Python是什么? Python是一種解釋型、高級、通用型編程語言,以簡潔明了、簡單易用著稱。它可以應用于網站開發、自動化腳本、數據分析、人工智能、系統操作等多種場景。 二、…

Objective-C面向對象編程:類、對象、方法詳解(保姆級教程)

目錄 一、核心概念 二、類的定義&#xff08;分.h和.m文件&#xff09; 1. 頭文件&#xff08;.h&#xff09;—— 公開聲明 2. 實現文件&#xff08;.m&#xff09;—— 具體實現 3. 屬性特性解析 原子性 所有權語義(ARC環境下) 讀寫控制 三、對象創建與內存管理 1…