乞版深克隆
<!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>
普通深克隆
<!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>
如何判断一个变量是不是数组
console.log(arr instanceof Array);
class的原型本质,怎么理解?
-
construtor
-
属性
-
方法
<!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>
-
原型
// class实际上是函数,可见是语法糖 typeof Animal // 'function' typeof Cat // 'function' // 隐式原型和显示原型 console.log(tom.__proto__ === Student.prototype)
-
原型关系
- 每个class都有显示原型
prototype
- 每个实例都有隐式原型
__proto__
- 实例的隐式原型===class的显示原型
- 每个class都有显示原型
-
基于原型的执行规则
- 获取对象的属性或方法时
- 先在自身上寻找是否有此属性和方法
- 若无此属性和方法,那就会自动去
__proto__
去寻找,如果__proto__
上也没有找到,则返回NULL
-
原型链
// 子类的显示原型上有一个隐式原型,它与父类的显示原型相等 console.log( Cat.prototype.__proto__ === Animal.prototype )