Deep clone
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 乞丐版深拷贝
// 缺点很明显:
// 1.当遇到RegExp,Error这些对象的时候,将只得到空对象
// 2.当遇到undefined,函数这些的时候会被忽略
// 3.当遇到NaN、Infinity和-Infinity这些的时候,会变成null
let User = {
name: "peter",
age: 18,
details: {
color: "orange",
size: 12
},
data: [new Date(1536627600000), new Date(1540047600000)],
func() {
console.log(123)
}
}
let User2 = JSON.parse(JSON.stringify(User));
User.details.color = 'yellow';
console.log(User);
console.log(User2);
</script>
</body>
</html>
Ordinary deep clone
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
// 继承函数递归赋值
let user = {
name: "peter",
age: 18,
details: {
color: "orange",
size: 12
},
data: [new Date(1536627600000), new Date(1540047600000)],
func() {
console.log(123)
}
}
function deepClone(obj) {
// 排除null情况
if (obj === null) return null;
// 排除不是object对象情况
if (typeof obj !== 'object') return obj;
// 排除正则
if (obj instanceof RegExp) new RegExp(obj);
// 排除Date对象
if (obj instanceof Date) new Date(obj);
// 创建新对象,使用原型继承的方式
let newObj = new obj.constructor
// 使用for in循环将之前的对象赋值给新对象
for (let val in obj) {
if(obj.hasOwnProperty(val)){
// 递归调用原对象,使其可以深克隆
newObj[val] = deepClone(obj[val]);
}
}
return newObj;
}
let user2 = deepClone(user);
user2.details.color = 'yellow';
console.log(user, user2);
console.log(user === user2);
</script>
</body>
</html>
How to determine whether a variable is an array
console.log(arr instanceof Array);
How to understand the prototype nature of class?
-
constructor
-
Attributes
-
method
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> class Student { constructor(name, number) { this.name = name; this.number = number; } sayHi(){ console.log(`姓名:${ this.name}\n学号:${ this.number}`) } } let lisi = new Student('李四', 28); lisi.sayHi() console.log(lisi.name) console.log(lisi.number) </script> </body> </html>
-
extends
-
super
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> class Animal { constructor(name, age) { this.name = name; this.age = age; } sayHi() { console.log(`姓名:${ this.name}\n年龄:${ this.age}`) } } class Cat extends Animal { constructor(name, age, type) { // super关键字用于访问和调用一个对象的父对象上的函数 super(name, age); this.type = type; } introduces() { console.log(`我叫${ this.name},今年${ this.age}岁了,属于${ this.type}`) } } let tom = new Cat('tom', 8, '猫科动物'); tom.introduces() </script> </body> </html>
-
prototype
// class实际上是函数,可见是语法糖 typeof Animal // 'function' typeof Cat // 'function' // 隐式原型和显示原型 console.log(tom.__proto__ === Student.prototype)
-
Prototype relationship
- Each class has a display prototype
prototype
- Each instance has an implicit prototype
__proto__
- The implicit prototype of the instance === the displayed prototype of the class
- Each class has a display prototype
-
Prototype-based execution rules
- When getting object properties or methods
- First look for this attribute and method on itself
- Without this attribute and method, it will automatically go
__proto__
to look for, if__proto__
on but could not find, NULL is returned
-
Prototype chain
// 子类的显示原型上有一个隐式原型,它与父类的显示原型相等 console.log( Cat.prototype.__proto__ === Animal.prototype )