ディープクローン
<!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);
クラスのプロトタイプの性質を理解する方法は?
-
コンストラクタ
-
属性
-
方法
<!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>
-
拡張します
-
素晴らしい
<!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)
-
プロトタイプの関係
- 各クラスにはディスプレイプロトタイプがあります
prototype
- 各インスタンスには暗黙のプロトタイプがあります
__proto__
- インスタンスの暗黙のプロトタイプ===表示されたクラスのプロトタイプ
- 各クラスにはディスプレイプロトタイプがあります
-
プロトタイプベースの実行ルール
- オブジェクトのプロパティまたはメソッドを取得するとき
- まず、この属性とメソッド自体を探します
- この属性とメソッドがないと、自動的
__proto__
に検索に移動します。__proto__
オンになっているのに見つからなかった場合は、NULLが返されます。
-
プロトタイプチェーン
// 子类的显示原型上有一个隐式原型,它与父类的显示原型相等 console.log( Cat.prototype.__proto__ === Animal.prototype )