一、值类型
let a = 100
let b = a
a = 200
console.log(b) // 100

二、引用类型
let a = { age: 20 }
let b = a
b.age = 21
console.log(a.age) // 21

三、类型
a.基本类型 undefined, null, string, number, boolean, Symbol
b.引用类型 数组,对象,函数,RegExp类型, date
1.null,undefined,undeclared的区别
a.null表示"没有对象",即该处不应该有值,转为数值时为0。典型用法是:
1.作为函数的参数,表示该函数的参数不是对象。
2.作为对象原型链的终点
3.typeof null
4.Number(null)
b.undefined表示"缺少值",就是此处应该有一个值,但是还没有定义,转为数值时为NaN。典型用法是:
1.变量被声明了,但没有赋值时,就等于undefined。
2.调用函数时,应该提供的参数没有提供,该参数等于undefined。
3.函数没有返回值时,默认返回undefined。
4.对象没有赋值的属性,该属性的值为undefined。
5.typeof undefined
6.Number(undefined)
c.undeclared:js语法错误,没有申明直接使用,js无法找到对应的上下文。
四、typeof运算符
a.判断所有值类型
let a; typeof a
const str = 'abc'; typeof str
const n = 100; typeof n
const b = true; typeof b
const s = Symbol('s'); typeof s
b.能判断函数
typeof console.log
typeof function () {}
c.能识别引用类型(不能再继续识别)
typeof null
typeof ['a', 'b']
typeof { x: 100 }
五、深拷贝和浅拷贝
区别:
1.深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝
a.浅拷贝
浅拷贝是会将对象的每个属性进行依次复制,但是当对象的属性值是引用类型时,实质复制的是其引用,
当引用指向的值改变时也会跟着变化。
可以使用 `Object.assign`、扩展运算符 `...` 、`for in`、
`Array.prototype.slice()`、`Array.prototype.concat()`
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = { ...a }
a.jobs.first = 'native'
console.log(b.jobs.first)
b.深拷贝
深拷贝复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。 深拷贝后的对象
与原来的对象是完全隔离的,互不影响,对一个对象的修改并不会影响另一个对象。
1.深拷贝最简单的实现是: `JSON.parse(JSON.stringify(obj))`
`JSON.parse(JSON.stringify(obj))` 是最简单的实现方式,但是有一些缺陷:
1.对象的属性值是函数时,无法拷贝。
2.原型链上的属性无法拷贝
3.不能正确的处理 Date 类型的数据
4.不能处理 RegExp
5.会忽略 symbol
6.会忽略 undefined
2.拷贝函数
const obj1 = {
age: 20,
name: 'xxx',
address: {
city: 'beijing'
},
arr: ['a', 'b', 'c'],
regexp: /^1[3456789]d{9}$/,
b: new Date()
}
function deepClone(obj) {
if (obj instanceof RegExp) return new RegExp(obj)
if (obj instanceof Date) return new Date(obj)
if (typeof obj !== 'object' || obj == null) return obj
let result = obj instanceof Array ? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = deepClone(obj[key])
}
}
return result
}
console.log(deepClone(obj1))
六、类型转换
六、类型转换
a.字符串拼接
const a = 100 + 10 // 110
const b = 100 + '10' // '10010'
const c = true + '10' // 'true10'
b.==运算符
100 == '100' // true
0 == '' // true
0 == false // true
false == '' // true
null == undefined // true
注意:
除了 == null之外,其他都一律用===,例如:
const obj = { x: 100 }
if (obj.a == null) {}
相等于
// if(obj.a === null || obj.a === undefined) {}
c.if语句和逻辑运算
1.truly变量: !!a === true 的变量
2.falsely变量: !!a === false 的变量
以下是falsely变量。除此之外都是truly变量
!!0 === false
!!NAN === false
!!'' === false
!!null === false
!!undefined === false
!!false === false
d.逻辑判断
console.log(10 && 0) // 0
console.log('' || 'abc') // 'abc'
console.log(!window.abc) // true
1.== 和 === 和 Object.is():方法判断两个值是否为同一个值 的区别
a.== 只比较值,如果类型不同,转换成相同的类型再比较,往String或者Number转
1.== 如果两边数据类型不同,转换规则如下:
1.布尔值===数值,则把布尔值转换为数值
2.字符串===数值,则通过Number()把字符串转为数值
3.如果一边是对象,则调用对象的valueof()方法后再比较
4.null和undefined相等
5.NaN和NaN不相等
6.如果两边都是对象,则比较他们是不是指向同一个对象
2.[] == ![] Type(x) 为boolean, 返回比较x == ToNumber(y)的结果
b.=== 类型和值都相等才相等
c.Object.is() 和 ===基本一样,只有下面这个区别
console.log(+0 === -0);
console.log(NaN === NaN);
console.log(Object.is(+0,-0));
console.log(Object.is(NaN,NaN));
七、JavaScript判断空数组的五种方法(前提知道是空数组)
1.将json对象转化为json字符串,再判断该字符串是否为"[]"(除外)
const arr = []
console.log(JSON.stringify(arr) === "[]")
2.instanceof运算符
const arr = []
arr instanceof === Array
3. Array.isArray(ES5的方法)
const arr = []
Array.isArray(arr)
4.constructor属性指向一个对象的构造函数
const arr = []
console.log(arr.constructor === Array)
5.Object.prototype.toString.call
(借用Object原型的call或者apply方法,调用toString()是否为[object Array])
const arr = []
Object.prototype.toString.call(arr) === '[object Array]'
6. Object.prototype.isPrototypeOf
使用Object的原型方法isPrototypeOf,判断两个对象的原型是否一样,
isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。
const arr = []
Array.prototype.isPrototypeOf(arr)
八、JavaScript判断空对象的四种方法
1.将json对象转化为json字符串,再判断该字符串是否为"{}"
const obj = {}
console.log(JSON.stringify(obj) === "{}")
2.constructor属性指向一个对象的构造函数(前提知道是空对象)
const obj = {}
console.log(obj.constructor === Object)
3.使用for...in循环遍历对象除Symol以外的所以可枚举属性,当对象有属性存在返回false,否则返回true
function isObjectEmpty(obj) {
if (obj.length === 0) return false
for (let key in obj) {
return false
}
return true
}
console.log(isObjectEmpty(obj))
4.使用ES6的Object.keys()方法(如果是空数组也会)
const obj = {}
const arr = Object.keys(obj)
console.log(arr.length === 0)
九、判断两个数组对象和对象是不是相同
通过 JSON.stringify() 把 JavaScript 对象转换为字符串。
const obj1 = { name: 'a', age: 12}
const obj2 = { name: 'a', age: 12}
console.log(JSON.stringify(obj1) === JSON.stringify(obj2))
const arr1 = [{ name: 'a', age: 12}]
const arr2 = [{ name: 'a', age: 12}]
console.log(JSON.stringify(arr1) === JSON.stringify(arr2))