- 1 Math
- 2 日期对象Date
- 3 数组对象Aarry
- 3.1 创建
- 3.2 判断是否为数组—-关键字 instanceof
- 3.3 判断是否为数组Array.isArray()
- 3.4 添加删除数据元素的方法
- 3.5 数组排序 反转
- 3.7 利用indexOf去重
- 3.8 数组转换为字符串
- 3.9 链接,截取,删除
- 3.10 数组方法forEach遍历数组
- 3.11 数组方法filter过滤数组
- 3.12 数组方法some—查找满足条件元素
- 3.13 Array.from()—类数组转换为数组
- 3.14 find()查找符合条件数组成员
- 3.15 findIndex() 查找索引
- 3.16 includes() 是否包含指定值
- 3.17 统计 reduce()
- 3.18 数组遍历map
- 4 字符串对象String
- 5 堆栈
- 6 简单类型和复杂类型传参
- 7 let关键字
- 8 const
- 11 箭头函数
- 13 扩展运算符
- 14 模版字符串
- 15 Set集合
- 16 Symbol
JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象。
内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
1 Math
1.1 常用方法
Math.PI // 圆周率
Math.floor() // 向下取整
Math.ceil() // 向上取整
Math.round() // 四舍五入 注意 -3.5 结果是 -3
Math.abs() // 绝对值
Math.max()/Math.min() // 求最大和最小值
Math.max(1, 3, 2)
1.2 随机数
random() 方法可以随机返回一个小数,其取值范围是 [0,1),左闭右开 0 <= x < 1
得到一个两数之间的随机整数,包括两个数在内
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
2 日期对象Date
2.1 创建
Date 对象和 Math 对象不一样,他是一个构造函数,所以我们需要实例化后才能使用
var now = new Date(); // 当前时间
var future = new Date('2019/5/1'); // 指定时间
2.2 输出日期
function get_date(dt) {
var year = dt.getFullYear()
var month = padZero(dt.getMonth() + 1)
var date = padZero(dt.getDate())
var day = dt.getDay()
var day_arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
var HH = padZero(dt.getHours())
var mm = padZero(dt.getMinutes())
var ss = padZero(dt.getSeconds())
return year + '年' + month + '月' + date + '日' + day_arr[day] + ' ' + HH + ':' + mm + ':' + ss
}
// 补零函数
function padZero(n) {
return n > 9 ? n : '0' + n
}
var now = new Date()
console.log(get_date(now));
还有一种使用padStart(位数, ‘要补上字符串’)
(dt.getSeconds()+'').padStart(2,'0')
2.3 获取毫秒数
// 实例化Date对象
var now = new Date();
// 1. 用于获取对象的原始值
console.log(date.valueOf())
console.log(date.getTime())
// 2. 简单写可以这么做
var now = + new Date();
// 3. HTML5中提供的方法,有兼容性问题
var now = Date.now();
2.4 倒计时
function count_down(params) {
var now = +new Date() // 返回的是当前时间总的毫秒数
var input_time = +new Date(params) // 返回的是用户输入时间总的毫秒数
var down_time = (input_time - now) / 1000
var d = parseInt(down_time / 60 / 60 / 24); // 天
d = d < 10 ? '0' + d : d;
var h = parseInt(down_time / 60 / 60 % 24); //时
h = h < 10 ? '0' + h : h;
var m = parseInt(down_time / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
var s = parseInt(down_time % 60); // 当前的秒
s = s < 10 ? '0' + s : s;
return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(count_down('2021-8-1'));
3 数组对象Aarry
3.1 创建
var arr = [1,"test",true];
var arr = new Array();
3.2 判断是否为数组—-关键字 instanceof
var arr = [1, 23];
var obj = {};
console.log(arr instanceof Array); // true
console.log(obj instanceof Array); // false
3.3 判断是否为数组Array.isArray()
var arr = [1, 23];
var obj = {};
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false
3.4 添加删除数据元素的方法
3.5 数组排序 反转
注意:sort方法需要传入参数来设置升序、降序排序
- 如果传入“function(a,b){ return a-b;}”,则为升序
- 如果传入“function(a,b){ return b-a;}”,则为降序 ```javascript var arr = [1, 64, 9, 6]; arr.sort((a,b)=> a-b) // 升序 console.log(arr); // [1, 6, 9, 64]
arr.sort((a,b)=> b-a) // 降序 console.log(arr); // [64, 9, 6, 1]
arr.reverse() // 反转 console.log(arr); // [1, 6, 9, 64]
<a name="GFNPf"></a>
## 3.6 数组索引方法
![image.png](https://cdn.nlark.com/yuque/0/2021/png/1688721/1625662248159-73f6df52-e89d-4c65-a637-ad70a6b78ba9.png#height=139&id=HYTbe&margin=%5Bobject%20Object%5D&name=image.png&originHeight=278&originWidth=1410&originalType=binary&ratio=1&size=168992&status=done&style=none&width=705)
```javascript
var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'];
console.log(arr.indexOf('z')); // 2
3.7 利用indexOf去重
var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']
var new_arr = []
for (let i = 0; i < arr.length; i++) {
if (new_arr.indexOf(arr[i]) === -1) {
new_arr.push(arr[i])
}
}
console.log(new_arr); // ["c", "a", "z", "x", "b"]
3.8 数组转换为字符串
注意:join方法如果不传入参数,则按照 “ , ”拼接元素
var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']
console.log(arr.join('--')); // c--a--z--a--x--a--x--c--b
console.log(arr.toString()); // c,a,z,a,x,a,x,c,b
3.9 链接,截取,删除
连接:
var arr1 = [1, 2]
var arr2 = [1, 2]
var arr3 = [1, 2]
var arr3 = arr1.concat(arr2, arr3)
console.log(arr3); // [1, 2, 1, 2, 1, 2]
截取:
var arr = [1, 2, 3, 4, 5]
console.log(arr.slice(1, 3)); // [2, 3]
其中结束的下标对应的值不截取
删除:
会影响原数组
var arr = [1, 2, 3, 4, 5]
arr.splice(1, 3)
console.log(arr); // [1, 5]
arr.splice(0, 0, '0') // 参数1:是索引,参数2:是要删除的个数, 以和替换
console.log(arr); // ["0", 1, 5]
3.10 数组方法forEach遍历数组
arr.forEach(function(value, index, array) {
//参数一是:数组元素
//参数二是:数组元素的索引
//参数三是:当前的数组
})
3.11 数组方法filter过滤数组
var arr = [12, 66, 4, 88, 3, 7];
var newArr = arr.filter(function(value, index,array) {
//参数一是:数组元素
//参数二是:数组元素的索引
//参数三是:当前的数组
return value >= 20;
});
console.log(newArr);//[66,88] //返回值是一个新数组
3.12 数组方法some—查找满足条件元素
some 查找数组中是否有满足条件的元素
var arr = [10, 30, 4];
var flag = arr.some(function(value,index,array) {
//参数一是:数组元素
//参数二是:数组元素的索引
//参数三是:当前的数组
return value < 3;
});
console.log(flag);//false返回值是布尔值,只要查找到满足条件的一个元素就立马终止循环
注意它返回值是布尔值, 如果查找到这个元素, 就返回true , 如果查找不到就返回false
和forEach区别:
- 如果查询数组中唯一的元素, 用some方法更合适,在some 里面 遇到 return true 就是终止遍历 迭代效率更高
- 在forEach 里面 return 不会终止迭代
3.13 Array.from()—类数组转换为数组
将类数组或可遍历对象转换为真正的数组
//定义一个集合
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
//转成数组
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组
let arrayLike = {
"0": 1,
"1": 2,
"length": 2
}
let newAry = Array.from(arrayLike, item => item * 2) //[2,4]
注意:如果是对象,那么属性需要写对应的索引
3.14 find()查找符合条件数组成员
用于找出第一个符合条件的数组成员,如果没有找到返回undefined
let ary = [{
id: 1,
name: '张三'
}, {
id: 2,
name: '李四'
}];
let target = ary.find((item, index) => item.id == 2);
console.log(target); // {id: 2, name: "李四"}
找数组里面符合条件的值,当数组中元素id等于2的查找出来,注意,只会匹配第一个
3.15 findIndex() 查找索引
用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1
let ary = [1, 5, 10, 15];
let index = ary.findIndex((value, index) => value > 9);
console.log(index); // 2
3.16 includes() 是否包含指定值
判断某个数组是否包含给定的值,返回布尔值。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
3.17 统计 reduce()
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
# callback 执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数
# accumulator 累计器累计回调的返回值
# currentValue 数组中正在处理的元素。
# index 可选 数组中正在处理的当前元素的索引
# array 可选 调用reduce()的数组
# initialValue 可选 作为第一次调用 callback函数时的第一个参数的值。如果没有提供初始值,则将使用数组中的第一个元素
统计有几个是完成的
const todos = [
{ id: "001", title: "吃饭", done: true },
{ id: "002", title: "打王者", done: false },
{ id: "003", title: "看小说", done: true },
{ id: "004", title: "睡觉", done: true },
]
const num = todos.reduce((acc, cur) => acc + (cur.done ? 1: 0), 0)
console.log(num); // 3
acc 累计器累计回调的返回值(即回调函数返回值就是acc的值)
cur 数组中正在处理的元素
0 作为第一次调用 callback函数时的第一个参数的值
数组连续相加
var numbers = [1,2,3,4,5]
const num = numbers.reduce((preValue, currentValue) => {
return preValue + currentValue
})
console.log(num); // 15
3.18 数组遍历map
和forEach()最大区别在于map有返回值,forEach没有**map()**
方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
const array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
callback
生成新数组元素的函数,使用三个参数:
currentValue``callback
数组中正在处理的当前元素。index
可选callback
数组中正在处理的当前元素的索引。array
可选map
方法调用的数组。
thisArg
可选执行 callback
函数时值被用作this
。
4 字符串对象String
4.1 字符串的不可变
指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。
由于字符串的不可变,在大量拼接字符串的时候会有效率问题
4.2 字符串索引方法
查找字符串”abcoefoxyozzopp”中所有o出现的位置以及次数
var str = 'abcoefoxyozzopp'
var arr = []
var index = str.indexOf('o')
while( index !== -1) {
arr.push(index)
index = str.indexOf('o', index+1)
}
console.log('出现位置:' + arr); // 出现位置:3,6,9,12
console.log('出现次数:' + arr.length); // 出现次数:4
4.3 根据索引返回字符串
案例:判断一个字符串 ‘abcoefoxyozzopp’ 中出现次数最多的字符,并统计其次数
var str = 'abcoefoxyozzopp'
// 创建对象,后通过key获取value
var o = {}
for (let i = 0; i < str.length; i++) {
var chars = str.charAt(i) // 根据位置返回字符
o[chars] ? o[chars]++ : o[chars] = 1 // 计算次数
}
console.log(o); // {a: 1, b: 1, c: 1, o: 4, e: 1, …}
// 遍历对象找最大值
var max = 0
var ch = ''
for (const k in o) {
if (o[k] > max) {
max = o[k]
ch = k
}
}
console.log('最多的字符' + ch); // 最多的字符o
console.log('最多的字符次数' + max); // 最多的字符次数4
4.4 连接,截取
连接:
var str1 = 'hello'
var str2 = 'world'
var str3 = str1.concat(' ', str2)
console.log(str3); // hello world
但是常用的是str1 + str2
截取str.substr():
var str = 'hello world'
var str4 = str.substr(1, 3)
console.log(str4); // ell
注意:第二个参数是个数
截取str.slice()
var str = 'hello world'
var str5 = str.slice(1, 3)
console.log(str5); // el
4.5 替换字符串replace
字符串.replace(被替换的字符串, 要替换为的字符串);
var str = 'hello world'
str = str.replace('el', 'abc') // habclo world
console.log(str);
4.6 切分字符串为数组
字符串.split(“分割字符”),在切分完毕之后,返回的是一个新数组。
var str = 'a,b,c,d';
console.log(str.split(',')); // ["a", "b", "c", "d"]
4.7 转换成大小写
- toUpperCase() //转换大写
- toLowerCase() //转换小写
var str = 'a,b,c,d';
var big_str = 'AVC'
console.log(str.toUpperCase()); // A,B,C,D
console.log(big_str.toLowerCase()); // avc
4.8 trim方法去除字符串两端的空格
str.trim()
trim() 方法并不影响原字符串本身,它返回的是一个新的字符串。
4.9 判断开头结尾startsWith() 和 endsWith()
- startsWith():表示参数字符串是否在原字符串的头部,返回布尔值
- endsWith():表示参数字符串是否在原字符串的尾部,返回布尔值
let str = 'Hello world!';
str.startsWith('Hello') // true
str.endsWith('!') // true
4.10 重复字符串repeat()
repeat方法表示将原字符串重复n次,返回一个新字符串'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
5 堆栈
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(引用类型,对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
简单类型(基本数据类型、值类型):在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null
复杂数据类型(引用类型):在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;
复杂数据类型的存储方式:
引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中
5.1 堆栈的释放
- 为执行函数分配的栈空间内存: 函数执行完自动释放
- 存储对象的堆空间内存: 当内存没有引用指向时, 对象成为垃圾对象, 垃圾回收器后面就会回收释放此内存
6 简单类型和复杂类型传参
6.1 基本类型的传递
函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。function fn(a) {
a++;
console.log(a); // 11
}
var x = 10;
fn(x);
console.log(x); // 10
6.2 复杂类型的传递
函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。
function Person(name) {
this.name = name;
}
function f1(x) { // x = p
console.log(x.name); // 刘德华
x.name = "张学友";
console.log(x.name); // 张学友
}
var p = new Person("刘德华");
console.log(p.name); // 刘德华
f1(p);
console.log(p.name); // 张学友
7 let关键字
7.1 块级作用域
let声明的变量只在所处于的块级有效
if (true) {
let a = 10;
}
console.log(a) // a is not defined
7.2 不存在变量提升
console.log(a); // a is not defined
let a = 20;
7.3 暂时性死区
利用let声明的变量会绑定在这个块级作用域,不会受外界的影响
var tmp = 123;
if (true) {
tmp = 'abc';
let tmp;
}
7.4 和var的区别
var arr = [];
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0](); // 2
arr[1](); // 2
关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的i值
let arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0](); // 0
arr[1](); // 1
关键点在于每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的i值
8 const
声明常量,常量就是值(内存地址)不能变化的量
常量不能重新进行赋值,如果是基本数据类型,不能更改值,如果是复杂数据类型,不能更改地址值
- 具有块级作用域
声明常量时必须赋值
const PI; // Missing initializer in const declaration
常量赋值后,值不能修改 ```javascript const PI = 3.14; PI = 100; // Assignment to constant variable.
const ary = [100, 200]; ary[0] = ‘a’; ary[1] = ‘b’; console.log(ary); // [‘a’, ‘b’]; ary = [‘a’, ‘b’]; // Assignment to constant variable.
<a name="csIGz"></a>
# 9 var const let 区别
- 使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
- 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
- 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值
![image.png](https://cdn.nlark.com/yuque/0/2021/png/1688721/1626684641132-8d3605f4-ea18-4e4c-8565-79ec259906ce.png#height=171&id=dlkZi&margin=%5Bobject%20Object%5D&name=image.png&originHeight=342&originWidth=1198&originalType=binary&ratio=1&size=55401&status=done&style=none&width=599)
<a name="NBxFO"></a>
# 10 解构赋值
ES6中允许从数组中提取值,按照对应位置,对变量赋值,对象也可以实现解构
- 解构赋值就是把数据结构分解,然后给变量进行赋值
- 如果结构不成功,变量跟数值个数不匹配的时候,变量的值为undefined
- 数组解构用中括号包裹,多个变量用逗号隔开,对象解构用花括号包裹,多个变量用逗号隔开
- 利用解构赋值能够让我们方便的去取对象中的属性跟方法
<a name="btC7l"></a>
## 10.1 数组解构
```javascript
let [a, b, c] = [1, 2, 3];
console.log(a)//1
console.log(b)//2
console.log(c)//3
//如果解构不成功,变量的值为undefined
10.2 对象解构
let person = { name: 'zhangsan', age: 20 };
let { name, age } = person;
console.log(name); // 'zhangsan'
console.log(age); // 20
let {name: myName, age: myAge} = person; // myName myAge 属于别名
console.log(myName); // 'zhangsan'
console.log(myAge); // 20
10.3 连续结构赋值加重命名
let obj = { a: { b: { c: 1 } } }
const {a:{b:{c:data}}} = obj
console.log(data); // 1
11 箭头函数
11.1 定义
() => {} //():代表是函数; =>:必须要的符号,指向哪一个代码块;{}:函数体
函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号
function sum(num1, num2) {
return num1 + num2;
}
//es6写法
const sum = (num1, num2) => num1 + num2;
如果形参只有一个,可以省略小括号
function fn (v) {
return v;
}
//es6写法
const fn = v => v;
11.2 箭头函数this指向
箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this
const obj = { name: '张三'}
function fn () {
console.log(this);//this 指向 是obj对象
return () => {
/* this 指向 的是箭头函数定义的位置,那么这个箭头函数定义在fn里面,
而这个fn指向是的obj对象,所以这个this也指向是obj对象*/
console.log(this);
}
}
const resFn = fn.call(obj);
resFn();
- 箭头函数中不绑定this,箭头函数中的this指向是它所定义的位置,可以简单理解成,定义箭头函数中的作用域的this指向谁,它就指向谁
- 箭头函数的优点在于解决了this执行环境所造成的一些问题。比如:解决了匿名函数this指向的问题(匿名函数的执行环境具有全局性),包括setTimeout和setInterval中使用this所造成的问题 ```javascript var age = 100;
var obj = { age: 20, say: () => { alert(this.age) // 100 } }
obj.say();
箭头函数this指向的是被声明的作用域里面,而对象没有作用域的,所以箭头函数虽然在对象中被定义,但是this指向的是全局作用域
- 箭头函数 this 指向声明时所在作用域下 this 的值
- 箭头函数不能作为构造函数实例化
- 不能使用 arguments
<a name="rKeee"></a>
# 12 剩余参数
剩余参数语法允许我们将一个不定数量的参数表示为一个数组,不定参数定义方式,这种方式很方便的去声明不知道参数情况下的一个函数
```javascript
function sum (first, ...args) {
console.log(first); // 10
console.log(args); // [20, 30]
}
sum(10, 20, 30)
剩余参数和解构配合使用
let students = ['wangwu', 'zhangsan', 'lisi'];
let [s1, ...s2] = students;
console.log(s1); // 'wangwu'
console.log(s2); // ['zhangsan', 'lisi']
13 扩展运算符
扩展运算符可以将数组或者对象转为用逗号分隔的参数序列
let ary = [1, 2, 3];
console.log(...ary); // 1 2 3,相当于下面的代码
console.log(1,2,3); // 1 2 3
13.1 通过扩展合并数组
// 方法一
let ary1 = [1, 2, 3];
let ary2 = [3, 4, 5];
let ary3 = [...ary1, ...ary2];
// 方法二
ary1.push(...ary2);
13.2 类数组转换成数组
将类数组或可遍历对象转换为真正的数组
let oDivs = document.getElementsByTagName('div');
oDivs = [...oDivs];
13.3 扩展运算符拷贝对象
let person = {name:'tom',age:18}
console.log({...person,name:'jerry',address:'家里蹲'});
console.log(person);
14 模版字符串
ES6新增的创建字符串的方式,使用反引号定义
let name = `zhangsan`;
let name = '张三';
let sayHello = `hello,my name is ${name}`; // hello, my name is zhangsan
let result = {
name: 'zhangsan',
age: 20,
sex: '男'
}
let html = ` <div>
<span>${result.name}</span>
<span>${result.age}</span>
<span>${result.sex}</span>
</div> `;
// 调用函数
const sayHello = function () {
return '哈哈哈哈 追不到我吧 我就是这么强大';
};
let greet = `${sayHello()} 哈哈哈哈`;
console.log(greet); // 哈哈哈哈 追不到我吧 我就是这么强大 哈哈哈哈
15 Set集合
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值
Set本身是一个构造函数,用来生成 Set 数据结构
const s = new Set();
// Set函数可以接受一个数组作为参数,用来初始化。
const set = new Set([1, 2, 3, 4, 4]);//{1, 2, 3, 4}
15.1 实例方法
- add(value):添加某个值,返回 Set 结构本身
- delete(value):删除某个值,返回一个布尔值,表示删除是否成功
- has(value):返回一个布尔值,表示该值是否为 Set 的成员
- clear():清除所有成员,没有返回值
const s = new Set();
s.add(1).add(2).add(3); // 向 set 结构中添加值
s.delete(2) // 删除 set 结构中的2值
s.has(1) // 表示 set 结构中是否有1这个值 返回布尔值
s.clear() // 清除 set 结构中的所有值
//注意:删除的是元素的值,不是代表的索引
15.2 遍历
Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。s.forEach(value => console.log(value))
16 Symbol
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。
它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)
比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因
Symbol 特点:
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol 值不能与其他数据进行运算
- Symbol 定义 的 对象属 性 不能 使 用 for…in 循 环遍 历 ,但是可以使用 Reflect.ownKeys 来获取对象的所有键名
16.1 创建Symbol
```javascript let s1 = Symbol(); console.log(s1, typeof s1); // Symbol() “symbol”
let s2 = Symbol(‘abcaa’) let s3 = Symbol(‘abcaa’) console.log(s2 === s3); // false console.log(s3); // Symbol(abcaa)
let s4 = Symbol.for(‘abcaa’) let s5 = Symbol.for(‘abcaa’) console.log(s4); // Symbol(abcaa) console.log(s4 === s5); // true
使用Symbol.for() 创建可以得到唯一个Symbol值
<a name="O3WwV"></a>
## 16.2 创建对象属性
Symbol的一个使用场景就是给对象添加属性,表示独一无二<br />由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名。<br />`Symbol`类型是为了解决属性名冲突的问题,顺带还具备模拟私有属性的功能。
```javascript
const val = Symbol()
let a = {
val: 20,
[val]: 'hello'
};
console.log(a[val]); // hello
console.log(a.val); // 20
console.log(a['val']); // 20
Symbol 值作为对象属性名时,不能用点运算符。