JS 基础进阶
文章目录
一、js基础语法
1.1 数据类型
typeof能检测哪些类型?
何时使用全等于,何时使用等于?
值类型和引用类型的区别?
1.1.1 es6值类型和引用类型
常见值类型:number、string、boolean、undefined、Symbol(‘s’)
常见引用类型:对象、数组、null(特殊引用类型,指向空指针)、函数(特殊引用类型 ,但不用于存储数据)
可通过typeof函数检测出具体的值类型和引用类型,
其中对象、数组和null通过typeof函数检测时只能检测出object对象,但无法指出具体属于哪一类;
值类型变量在赋值时两个变量指向不同的内存地址,进行的是深拷贝
引用类型变量在赋值时指向同一个内存地址,进行的是浅拷贝
a=1;b=a;b=2;console.log(a) //1 深拷贝
a={
'name':'zhangsan','age':18}; b=a; b.age=19;console.log(a.age); //19 浅拷贝
- 深拷贝代码:
/**
* 深拷贝
*/
const obj1 = {
age: 20,
name: 'xxx',
address: {
city: 'beijing'
},
arr: ['a', 'b', 'c']
}
const obj2 = deepClone(obj1)
obj2.address.city = 'shanghai'
obj2.arr[0] = 'a1'
console.log(obj1.address.city)
console.log(obj1.arr[0])
/**
* 深拷贝
* @param {Object} obj 要拷贝的对象
*/
function deepClone(obj = {
}) {
if (typeof obj !== 'object' || obj == null) {
// obj 是 null ,或者不是对象和数组,直接返回
return obj
}
// 初始化返回结果
let result
if (obj instanceof Array) {
result = []
} else {
result = {
}
}
for (let key in obj) {
// 保证 key 不是原型的属性
if (obj.hasOwnProperty(key)) {
// 递归调用!!!
result[key] = deepClone(obj[key])
}
}
// 返回结果
return result
}
1.1.2 let定义变量与var定义变量的区别:
let定义的变量可在各个块作用域中使用,而var定义的变量只能在全局作用域中使用==
注意下面代码中变量i的作用域
let a
for (let i = 0; i < 10; i++) {
a = document.createElement('a')
a.innerHTML = i + '<br>'
a.addEventListener('click', function (e) {
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
1.1.3 堆栈模型
堆栈模型:值类型一般在栈中存储,引用类型一般在堆中存储
1.2 Symbol ,表示独一无二的值。
Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
let s = Symbol()
typeof s
// "symbol"
变量s就是一个独一无二的值。typeof的结果说明s是 Symbol 数据类型。
既然是独一无二的,那么两个Symbol()就一定是不相等的:
let s1 = Symbol()
let s2 = Symbol()
console.log(s1)
console.log(s2)
console.log(s1 === s2) // false
注意
==Symbol函数前不能使用new命令,否则会报错。==这是因为生成的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。
Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
1.2.1 Symbol.for()
Symbol.for() 接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
let s1 = Symbol.for('foo')
let s2 = Symbol.for('foo')
console.log(s1 === s2) // true
注意
Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。
Symbol.keyFor()方法返回一个已登记的 Symbol 类型值的key。
const s1 = Symbol(