symbol
它是一个内置全局函数,生成一个独一无二的数据
symbol值是通过
Symbol函数生成
的
symbol值是
独一无二
的值
let s = Symbol();
let s1 = Symbol();
console.log(s1 === s); //false
symbol值可以作为标识符,作为对象的属性名
属性名是表达式要用[ ]括起来
// 第一种写法
let a = {};
a[Symbol()] = 'csdn';
// 第二种写法
let a = {
[Symbol()]: 'csdn'
};
// 第三种写法
let a = {};
Object.defineProperty(a, Symbol(), { value: 'csdn' });
// 以上写法都得到同样结果
a[Symbol()] // "csdn"
symbol函数允许接收一个字符串作为参数,表示对symbol值的表述,
如果是其他类型的值,会调用该方法的toString()
注意:没有symbol值是相同的,即使它们用有相同的描述
let s2 = Symbol("hello");
let s3 = Symbol("csdn");
console.log(s2,s3); //Symbol(hello) Symbol(csdn)
symbol.for()和symbol(),不同的是前者会被登记在全局环境中提供搜索而后者不会
let s4 = Symbol.for("s4");
let s5 = Symbol.for("s4");
console.log(s4 == s5); //true
let s6 = Symbol.for("s6");
let s7 = Symbol("s6");
console.log(s6 == s7); //false
另外,Symbol 值也可以转为布尔值,但是不能转为数值
let s = Symbol();
Boolean(s) // true
Number(s) // 报错
Symbol 作为属性名,遍历对象的时候,
不会被 for…in、for…of、Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 遍历。
但是Object.getOwnPropertySymbols()可以
获取指定对象的 Symbol 属性名。
set
set它类似于数组,但是成员的值都是唯一的,没有重复的值。
传入的参数是数组(或者具有 iterable 接口的其他数据结构)。
Set本身是一个构造函数,用来生成 Set 数据结构。
let s1 = new Set([1,2,3,2]);
console.log(s1); //set(3) {1,2,3}
数组去重
let arr = [1,1,2,3,4,2,5];
arr = [...new Set(arr)]; //...此时是扩展运算符
console.log(arr); //[1,2,3,4,5]
字符串的去重
let str = "aabcba";
str = Array.from(new Set(str)).join(""); //先转数组再转成字符串
console.log(str); //abc
set的属性
set.prototype.constructor
:构造函数,Set()
set.prototype.size
:返回set实例的成员总数
set.prototype就是构造的实例对象
set的方法
let s1 = new Set([1,2,3,2]);
// 增
s1.add(2);
console.log(s1);
// 删
s1.delete(2);
console.log(s1);
// 判断当前成员是否存在于set结构
console.log(s1.has(2));
//清除所有
s1.clear();
console.log(s1);
set实现并集交集和差集
let a=new Set([1, 2, 3, 22]);
let b=new Set([1, 22, 13, 2]);
let c=new Set([...a,...b]);
console.log(c);//并集
let d=new Set([...a].filter(item => b.has(item)));
console.log(d);//交集
let e=new Set([...a].filter(item => !b.has(item)));
console.log(e);//a对于b差集
let f=new Set([...b].filter(item => !a.has(item)));
console.log(f);//b对于a差集
map
let obj = {};
let obj2 = {};
obj[obj2] = 111;
console.log(obj);
属性名被强转成了字符串
为了解决上述这个问题,ES6 提供了 Map 数据结构。
它类似于对象,也是键值对的集合。
不同
的是:
Object
结构提供了“
字符串—值
”的对应,
Map
结构提供了“
值—值
”的对应,是一种更完善的 Hash 结构实现。
也就是说 键”的范围不限于字符串,
各种类型的值(包括对象)都可以
当作键
let m1 = new Map(); //Map()也是一个内置构造函数
console.log(m1);
// 增
m1.set(obj2,111);
m1.set(true,333);
m1.set(666,333);
m1.set(" ",333);
console.log(m1);
// 删
m1.delete(obj2)
console.log(m1);
// 改
m1.set(obj2,222);
console.log(m1);
// 查
console.log(m1.get(obj2)); //222
// 判断当前成员是否存在于map结构
console.log(m1.has(666));
// 清除所有
m1.clear()
console.log(m1);
class
class 类 完全可以看做是构造函数的另一种写法 一个语法糖
constructor是类的默认方法,指向这个类本身,通过new调用类时会自动调用constructor
直接定义在类中的方法,创建在类的原型对象上
class Person {
constructor(name) {
// constructor中的this指向实例的对象
this.name = name,
this.say = function () {
console.log(this.name);
}
}
let p1 = new Person();
// 类只能通过new调用
console.log(p1);
aa.hasOwnProperty(“bb”) : 判断aa对象中是否有bb属性(不包括继承的属性)
“bb” in aa : 判断aa对象中是否有bb属性 (包括继承的属性)
在类中遵循严格模式
(在严格模式中指向全局的this不再是window,而是undefined)
class Person {
constructor(name) {
this.name = name,
this.say = function () {
console.log(this.name);
}
}
run() {
console.log(this.name);
}
}
let p3 = new Person("csdn");
let { run } = p3; //解构赋值,在全局run=run() { console.log(this.name) }
run(); //报错 此时this指向undefined, undefined中没有'name'属性
class Person {
constructor(name) {
this.name = name,
this.say = function () {
console.log(this.name);
}
this.run = this.run.bind(this); //第一个this指向创建的实例对象,里面建一个run属性,第二个this也是指向创建的实例对象,this.run此时实例对象中找不到run对应的键值,在它的原型链往上找有一个run()方法,第三个this也是指向创建的实例对象,run.bind修改了run()方法的指向
}
run() {
console.log(this.name);
}
}
let p3 = new Person("hello");
let p4 = new Person("world");
let { run } = p4;
run(); //world