一)集合对象
1) Set对象
Set对象是一组值的集合,这些值是不重复的,无序的,与我们在数学中学到的集合是一样的。我们可以往里面添加、删除、查询数据。
//先声明一个Set对象:
var mySet = new Set();//创建Set对象
//往这个集合对象中添加元素:
mySet.add(1);
mySet.add("some text");;//在Set对象尾部添加一个元素。返回该Set对象。
//判断集合中是否存在一个元素1:
mySet.has(1); // true 返回一个布尔值,表示该值在Set中存在与否。
//删除集合中的字符串“foo”:
mySet.delete("foo");//移除Set的中与这个值相等的元素
//获取集合中元素的数量:
mySet.size; // 2返回Set对象的值的个数。
//删除集合中所有的元素:
mySet.clear();//移除Set对象内的所有元素。
注意: Array可以使用下标,Map和Set不能使用下标,ES6引入了iterable类型,
Array,Map,Set都属于iterable类型,它们可以使用for...of循环来遍历。
2)map对象
如果你需要一个键值对的数据结构,我们可以声明一个Map对象,这个 对象里面可以包含多个项目,每个项目都有一个名字,还有一个跟它对应的值。
//创建Map对象的方法是使用new操作符去声明这个对象
var myMap = new Map();
//向Map对象里面添加键值对,其中键和值可以是任意值(对象或者原始值)
var obj = {};
var fun = function(){};
var str = “HelloWorld”;
myMap.set(obj, “我是对象”);
myMap.set(fun, “我是函数”);
myMap.set(str, “我是字符串”);
//查看集合中元素的数量
myMap.size
//获取相应的键值
myMap.get(obj);
//删除一个键值对,然后再判断该键值对是否存在
myMap.delete(fun);
myMap.has(fun);
//删除Map集合中所有的键值对
myMap.clear();
二)class
JavaScript语言的传统方法是通过构造函数,定义并生成新对象。下面是一个例子。
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
上面这种写法跟传统的面向对象语言(比如C++和Java)差异很大,很容易让新学习这门语言的程序员感到困惑。
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用ES6的“类”改写,就是下面这样:
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
注意:
上面代码定义了一个“类”,可以看到里面有一个constructor方法, 这就是构造方法,而this关键字则代表实例对象。也就是说,ES5的构造函 数Point,对应ES6的Point类的构造方法。
Point类除了构造方法,还定义了一个toString方法。注意,定义“类” 的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进 去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。
构造函数的prototype属性,在ES6的“类”上面继续存在。事实上, 类的所有方法都定义在类的prototype属性上面。
由于类的方法都定义在prototype对象上面,所以类的新方法可以添加 在prototype对象上面。Object.assign方法可以很方便地一次向类添加多 个方法。
class Point {
constructor(){
// ...
}
}
Object.assign(Point.prototype, {
toString(){},
toValue(){}
});
另外,类的内部所有定义的方法,都是不可枚举的(non-enumerable)
console.log(Object.getOwnPropertyNames(Point.prototype));
var x = Object.getOwnPropertyDescriptor(Point.prototype, 'toString');
console.log(x);
上面代码中,toString方法是Point类内部定义的方法,它是不可枚举的。这一点与ES5的行为不一致。
Class的继承(重点):
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
talk() {
console.log("do not talk");
}
// 不会被继承, 而且调用时,只能 -- 类名.函数名
static mySelfFn() {
console.log("wo shi static fn");
}
}
//extends关键字用于实现类之间的继承。子类继承父类,就继承了父类的所有属性和方法。
class Lion extends Cat {
constructor(name){
super(name);
}
speak() {
// 使用super可以调用父类的方法
console.log(this.name + ' roars.');
}
get name() {
return this._name.toUpperCase();
}
set name(value) {
this._name = value;
}
}
var p = new Lion("病猫");
p.talk();
p.speak();
getter和setter:
get name() {
return this._name.toUpperCase();
}
set name(value) {
this._name = value;
}