【力扣 (LeetCode)】38. 外觀數列
阿新 • • 發佈:2021-01-12
技術標籤:javascript
物件
定義
- 無序的資料結婚
- 鍵值對的集合
寫法
-
* let obj = { 'name' : 'rain' , 'age' : 13}; * let obj2 = new Object({}) * console.log({'name' : 'frank' , 'age' :13})
細節
- 鍵名是字串,不是識別符號,可以包含任意字元
- 引號可省略,省略之後就只能寫識別符號
- 就算引號省略了,鍵名也還是字串(重要)
屬性名
-每個key都是物件的屬性名(property)
屬性值
-每隔value都是物件的屬性值
奇怪的屬性名
-
所有屬性名會自動變成字串
-
let obj = { 1:'a', 3.2:'b', 1e2:true, 1e-2:true, .234:true, 0xFF:true }; Object.keys(obj) //不是按順序存 =>["1","100","255","3.2","0.01","0,234"];
-
細節:
- Object.keys(obj)可以得到obj的所有key
-
變數作屬性名
-
如何用變數做屬性名
-
之前都是用常量做屬性名
-
let p1 = 'name' let obj = { p1 : 'rain'}這樣寫,屬性名為'p1' let obj = {[p1] : 'rain'}這樣行,屬性名為'name'
-
-
對比
- 不加[ ]的屬性名會自動變成字串
- 加了[ ]則會當作變數求值
- 值如果不是字串,則會自動變成字串
物件的隱藏屬性
-
隱藏屬性
- JS中每一個物件有有一個隱藏屬性
- 這個隱藏屬性儲存著其共有屬性組成的物件的地址
- 這個共有屬性組成的物件叫做原型
- 也就是說,因讓屬性儲存著原型的地址
-
程式碼示例
-
var obj = {} obj.toString() //居然不報錯
-
因為obj的因讓屬性對應的物件上有toString()
-
超綱知識
除了字串,symbol也能做屬性名
let a = Symbol()
let obj = { [a] : 'Hello'}
- 這有什麼用????
- 目前,屁用都有沒有,很久過很久以後會有用
- 再學習【迭代】時會用到
刪除屬性
-
delete obj.xxx或 delete obj['xxx']
- 即可刪除obj的xxx屬性
- 請區分[屬性值為undefined]和[不含屬性名]
-
不含屬性名
-
'xxx' in obj === false
-
-
含有屬性名,但是值為undefined
-
'xxx' in obj && obj.xxx ===undefined
-
-
注意 obj.xxx === undefined
- 不能斷定’xxx’ 是否為obj的屬性
-
類比
- 你有沒有衛生紙?
- A:沒有 //不含屬性名
- B:有,但是沒帶 //含有屬性名,但是值為undefined
程式設計師就是這麼嚴謹
--沒有就是沒有,undefined就是undefined ,絕不含糊
檢視所有屬性(讀屬性)
-
檢視自身所有屬性
-
Object.ke ys(obj)
-
-
檢視自身屬性+共有屬性
-
console.dir(obj) 或者自己依次用 Object.keys打印出obj.__proto__
-
-
判斷一個屬性是自身的還是共有的
-
obj.hasOwnProperty('toString')
-
原型
- 每個物件都有原型
- 原型裡存摺物件的共有屬性
- 比如obj的原型就是一個物件
- obj.__protp__存著這個物件的地址
- 這個物件裡有toString / valueOf/ length等屬性
- 物件的原型也是物件
- 所以物件的原型也有原型
- obj = {} 的原型即為所有物件的原型
- 這個原型包含所有物件的共有屬性,是物件的根
- 這個原型也有原型,是null
檢視屬性
- 兩種方法檢視屬性
- 中括號語法: obj [‘key’]
- 點語法 : obj.key
- 坑新人語法: obj[key] //變數key值一般不為’key’
- 請優先使用中括號語法
- 點語法會誤導你,讓你以為key不是字串
- 等你確定不會弄混兩種語法,再改用點語法
修改或增加屬性(寫屬性)
-
直接賦值
-
let obj = {name : 'frank'} //name是字串 obj.name = 'frank' //name是字串 obj['name'] = 'frank' ************************************************* 錯錯錯錯錯錯錯obj[name] = 'frank' //錯錯錯錯錯錯錯,因為name值不確定 ************************************************* obj['na' + 'me'] = 'frank' let key = 'name'; obj[key] = 'frank' let key = 'name' ************************************************* 錯錯錯錯錯錯錯obj.key = 'frank' 錯錯錯錯錯錯錯 ,因為這個key是字串 這個obj.key 等價於 obj['key'] *************************************************
-
-
批量賦值
-
Object.assign(obj,{'age':18,'gender':'man','name':'rain'})
-
修改或增加共有屬性
-
無法通過自身修改或增加共有屬性
-
let obj = {}, obj2 = {} //共有屬性toString等 obj.toString = 'xxx' 只會再改obj自身屬性 obj2.toString還是在原型上
-
-
我偏要修改或增加原型上的屬性
-
obj.__proto__.toString='xxx' //不推薦用__proto__ Object.prototype.toString = 'xxx' 一般來說,不要修改原型,會引起很多問題
-
修改隱藏屬性
-
不推薦使用__proto__
-
let obj = {name:'frank'} let obj2 = {name : 'jack'} let common = {kind: 'human'} obj.__proto__ = common obj2.__proto__ = common
-
-
推薦使用Object.create
-
let obj = Object.create(common) obj.name = 'frank' let obj2 = Object.create (common) obj2.name ='jack' 規範大概的意思是,要改就一開始就改,別後來再改
-
總結
-
刪
-
delete obj['name'] //只刪屬性,刪別的最好不要用 'name' in boj //false 有問題,沒辦法區別這個屬性是自己的還是原型上共有的,所以用底下這個hasOwnProperty obj.hasOwnProperty('name') //false 只有自身沒這個屬性才返回false
-
-
查
-
Object.keys(obj) 查所有key console.dir(obj) 通過目錄檢視 obj['name'] obj.name //記住這裡的name是字串 obj[name] //記住這裡的name是變數 查屬於讀,會看原型鏈
-
-
改
-
改自身obj['name'] = 'jack' 批量改自身Object.assign(obj,{age:18,.......}) 改共有屬性obj.__proto__['toString'] = 'xxx' 改共有屬性Object.prototype['toString'] = 'xxx' 改原型let obj = Object.create(common)
- 注:所有proto程式碼都是強烈不推薦的
-
-
增
- 基本同上:已有屬性則改;沒有屬性則增
最後
- 在操作一個物件的屬性時,一定要分清字串和變數
- obj.[‘name’] === obj.name
- 但是obj[name]和上面兩個都不一樣,他是去找尋以name為變數名的這個變數的值。
- 例如我們在上面寫了一個 let name = “哈哈哈哈哈我是小紅”
- 那麼這個obj[name] 的意思就是 obj[‘哈哈哈哈哈我是小紅’]