一、值类型与引用类型
值类型:String、Number、Boolean、Symbol
引用类型:JSON、Array、null
演示值类型与引用类型的堆栈模型
变种提问
const a={x:100, y:200}
const b=a
let c=a.x
b.x=300
console.log(a) // x:300
二、深拷贝
如何实现深拷贝
JSON.parseJSON.stringify(obj))
不能存放函数、时间对象、正则递归
没有考虑循环引用lodash.cloneDeep
推荐,工作中没必要重复造轮子
1.JSON.parseJSON.stringify(obj))
<script>
const obj1 = {
name: "张三",
age: 18,
address: {
city: "北京",
},
hobby: ["台球", "篮球"],
fn:function(){
console.log(123);
},
};
const obj2 = deepClone(obj1);
obj2.address.city = "上海";
//
console.log(obj1.address.city); //北京
console.log(obj2.address.city); //上海
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
// 不能存放函数、时间对象、正则
}
</script>
2.递归
<script>
const obj1 = {
name: "张三",
age: 18,
address: {
city: "北京",
},
hobby: ["台球", "篮球"],
fn:function(){
console.log(123);
},
};
const obj2 = deepClone(obj1);
obj2.address.city = "上海";
function deepClone(obj){
if(typeof obj !=="object" || obj==null){
return obj;
}
let res=obj instanceof Array ? [] : {};
for(let key in obj){
if(obj.hasOwnProperty(key)){
res[key]=deepClone(obj[key]);
}
}
return res;
// 没有考虑循环引用
}
console.log(obj1);
console.log(obj2);
</script>
三、==和===的区别
隐式类型转换
<script>
console.log(100 == "100");
console.log(100 === "100");
console.log(0 == "");
console.log(0 === "");
console.log(0 == false);
console.log(0 === false);
console.log(false == "");
console.log(false === "");
console.log(null == undefined);
console.log(null === undefined);
let obj = {
// age: 18,
};
console.log(obj==null);
// obj==null 是 obj===null||obj===undefined 的缩写
console.log(obj===null||obj===undefined);
</script>
只有obj==null使用双等
四、truly和falsely变量
什么是truly变量? 什么是falsely变量?
truly变量:!!val===true
falsely变量:!!val===false
除了falsely变量,都是truly变量
数字0
NaN
空字符串
NULL
undefined
<script>
console.log(!!""===false)
console.log(!!NaN===false);
console.log(!!0===false);
console.log(!!null===false);
console.log(!!undefined===false);
</script>
五、原型和原型链
复习class基础语法
class
construct
extends
super
instanceof
<script>
// 声明类
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`你好 ${this.name}`);
}
}
// 实例化
let zhangsan = new Person("zangsan", 18);
console.log(zhangsan.name);
console.log(zhangsan.age);
zhangsan.sayHello();
</script>
原型
原型链
<script>
// 类
// 父类
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`你好 ${this.name}`);
}
}
// 子类 继承
class Student extends Person {
constructor(name, age, sex) {
super(name, age);
this.sex = sex;
}
learn() {
console.log(
`我是${this.name},今年${this.age}岁,${this.sex},在学习英语`
);
}
}
//实例
// 实例化
let zhangsan = new Student("张三", 18, "男");
console.log(zhangsan);
zhangsan.sayHello();
zhangsan.learn();
console.log(zhangsan instanceof Student);
console.log(zhangsan instanceof Person);
console.log(zhangsan instanceof Object); //所有原型的头头
console.log(zhangsan instanceof Array);
// 原型 原型链
console.log(zhangsan.__proto__); //隐式原型 实例
console.log(Student.prototype); //显式原型 class/类
console.log(zhangsan.__proto__ === Student.prototype);
</script>
六、手写instanceof
instanceof
instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上
可以判断继承关系,只要是在一条原型链上就可以返回true
<script>
// 类
// 父类
class Person {
constructor(name) {
this.name = name;
}
}
// 子类 继承
class Student extends Person {
constructor(name, age) {
super(name);
this.age = age;
}
}
//实例
// 实例化
let zhangsan = new Student("张三", 18);
console.log(myInstanceof(zhangsan, Student));
console.log(myInstanceof(zhangsan, Person));
console.log(myInstanceof(zhangsan, Object));
function myInstanceof(obj1, obj2) {
let obj1Proto = obj1.__proto__;
while (true) {
if (obj1Proto === null) {
return false;
}
if (obj1Proto === obj2.prototype) {
return true;
}
obj1Proto = obj1Proto.__proto__;
}
}
</script>