深拷貝
值型別的賦值就是深拷貝:變數賦值時,拷貝的不是記憶體地址,而是將資料完整的在記憶體中復制了一份
const a = 10
const b = a
console.log(b);

淺拷貝
參考型別(null 物件 陣列)的賦值操作都不是深拷貝:拷貝的是記憶體地址,最終兩個變數指向的是同一個地址
const a = {
name: 'jj',
age: 20
}
const b = a
b.age = 18
console.log(a.age); // 18

深拷貝和淺拷貝的區別
- 淺拷貝只復制一層物件的屬性,而深拷貝則遞回復制了所有層級
- 淺拷貝有效性針對的是單一層級物件 [1,2,3]或者{a:1,b:2}
- 深拷貝有效性針對的是單層或者多層級物件 [1,2,3]或者{a:1,b:2}或者[1,[1],{a:1}]或者{a:[1],b:{c:2}}
如何讓參考型別深拷貝
簡單的實作深拷貝
const p1 = {
name: 'jj',
age: 20
}
const deepClone = (obj) => {
let result = {}
for (let i in obj) {
// console.log(obj[i]);
result[i] = obj[i]
}
return result
}
const p2 = deepClone(p1)
p2.age = 12
console.log(p1, p2);

加入遞回
const p1 = {
name: 'ss',
age: 20,
address: {
province: '河北省',
city: '保定市',
area: '蓮池區',
info: '河北軟體職業技術學院'
}
}
const deepClone = (obj) => {
let result = {}
for (let i in obj) {
result[i] = obj[i]
}
return result
}
const p2 = deepClone(p1)
p2.age = 2
p2.address.city = '衡水'
console.log(p1, p2);
輸出結果

-
對于name和age屬性手機深拷貝
-
對于address屬性不是深拷貝
-
深拷貝的核心是我沒找到物件或數值中的值型別(age 和 name屬性的值),然后進行賦值操作,就是深拷貝,而address屬性是一個物件自然采用記憶體地址拷貝
-
解決方案:加入遞回,一致遞回到值型別為止
-
在deepClone函式中的回圈改寫為:
result[i]=deepclone(obj[i])
完整代碼
const deepClone = (obj) => {
// 如果不是物件或者等于null的時候無需進行深拷貝
if (typeof obj !== 'object' || obj == null) {
return obj
}
//宣告變數,用于存盤拷貝的資料
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let i in obj) {
// console.log(deepClone(obj[i]));
result[i] = deepClone(obj[i])
}
return result
}
const p1 = {
name: 'ss',
age: 20,
address: {
province: '河北省',
city: '保定市',
area: '蓮池區',
info: '河北軟體職業技術學院'
}
}
const p2 = deepClone(p1)
p2.age = 2
p2.address.city = '衡水'
console.log(p1, p2);
原型和原型鏈
隱式原型和顯示原型
class People {
constructor(name) {
this.name = name
}
eat() {
console.log('eat');
}
}
class Student extends People {
constructor(name, number) {
super(name)
this.number = number
}
sayHi() {
console.log(`姓名:${this.name},學號:${this.number}`);
}
}
const xialuo = new Student('夏洛特', '110')
console.log(xialuo.__proto__ === Student.prototype);//true
console.log(xialuo.__proto__);//物件的物件原型,也是隱式原型
console.log(Student.prototype);//類的原型物件,也是顯示原型
物件的隱式原型與類的顯式原型是同一個物件,記憶體地址一致

原型關系
- 每個class都有顯示原型prototype
- 每個實體都有隱式宣告__proto__
- 實體的__proto__指向對應的class的prototype
獲取屬性方法時
const xialuo = new Student('夏洛特', '110')
console.log(xialuo.name);//夏洛特
xialuo.sayHi()
xialuo.eat()
- 獲取屬性或方法時,首先在物件的自身屬性中查找如上面name就是物件的自身屬性
- 如果找不到,則自動取__proto__中查找,如上面的sayHi方法,在物件中并沒有,所有取物件的隱式原型上查找
原型鏈
hasownProperty 方法判斷某個屬性或者方法是否在當前隱式原型中
在 JavaScript 中,每個物件都有一個指向它的原型(prototype)物件的內部鏈接(proto),這個原型物件又有自己的原型,直到某個物件的原型為 null 為止(也就是不再有原型指向),這種一級一級的鏈結構就稱為原型鏈(prototype chain), 當查找一個物件的屬性時,JavaScript 會向上遍歷原型鏈,直到找到給定名稱的屬性為止;到查找到達原型鏈的頂部(Object.prototype),仍然沒有找到指定的屬性,就會回傳 undefined,

所有 class 都是從 Object 繼承的,也就是說 Object 是其他類的原型
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/287746.html
標籤:其他
