1.class类
1)介绍
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。
通过class关键字,可以定义类。ES6 的class可以看作是构造函数一个语法糖
语法糖:具有特殊功能的代码写法,内部封装了一些方法,让一些复杂代码的编写及其用法变得简单
2)构造器
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。
一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
// 定义一个类
class Person{
// 类的默认方法 显式添加 调用添加的构造器
constructor(name,age,weight){
// 维护实例的私有属性
this.name=name;
this.age=age;
this.weight=weight;
}
// 其实是存放在类构造器函数的原型对象当中的
// 公有方法
sayName(){
console.log(this.name)
}
}
let p=new Person('zhangsan',12,'10kg');
let p1=new Person('lisi',20,'20kg');
console.log(p,p1);
console.log(p.sayName===p1.sayName);
//Person { name: 'zhangsan', age: 12, weight: '10kg' }
//Person { name: 'lisi', age: 20, weight: '20kg' }
//true
3)实例方法、属性
定义在类体中的方法称为实例方法。如下,sayName方法就是实例方法,
本质上该方法应该是声明在Person.prototype中,可供所有的实例调用,因此称为实例方法。
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
sayName(){
console.log("i am ",this.name);
}
}
4)静态方法、属性
通过static关键字来定义静态属性和静态方法。
静态属性和静态方法是定义在类【构造函数】上的,所以可以通过类【构造函数】直接访问。
在静态方法中,this指向当前类【构造函数】
class Person{
static num = 200;
static number(){
return this.num;
}
}
console.log(Person.number()); //200
//实例方法实例属性写在哪
//实例方法和属性可以由类构造函数创建的实例调用呀
// 静态属性和静态方法写在哪
// 类构造函数调用
5)继承
ES5继承
借用构造函数继承
function Animal() {}
function Dog() {
Animal.call(this)
}
原型链继承
子构造函数的原型指向父构造函数的实例
Dog.prototype = new Anmimal()
Dog.prototype = Anmimal.prototype
ES6继承
用法
class Dog extends Anmimal {
constructor(name,age,weight) {
super(name,age);
}
}
let dog = new Dog('二狗',1,'10KG')
子类继承父类(构造函数继承,继承静态方法、属性)
子类的构造函数继承父类的构造函数
子类构造函数的原型对象指向父类构造函数
Dog.__proto__ === Animal
子类原型对象继承父类原型对象(方法继承,继承实例方法、属性)
Dog.prototype.__proto__ === Animal.prototype
dog.__proto__.__proto__ === Animal.prototype
2.Symbol
1)介绍
ES6 引入的一种新的原始数据类型Symbol,表示独一无二的值,属于基本数据类型
Symbol函数可以接受参数,表示对于这个唯一值的描述。
特点:
1)Symbol的值是唯一的,用来解决命名冲突的问题
2)Symbol值不能与其他数据进行运算
3)Symbol定义的对象属性不能使用for…in循环遍历
2)使用
Symbol()函数会返回symbol类型(基本数据类型)的值
let s = Symbol()
typeof s ; //’symbol’
symbol类型的值是独一无二的
在对象中使用symbol
用于对象的属性名,就能保证不会出现同名的属性。
这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖
let sy1 = Symbol();
obj[sy1] = 'hello'
let obj2 = {
...obj1,
// key为变量时,需要用[]包裹
[sy1]: 'world'
}
3)Symbol.for()
它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
Symbol.keyFor()
检测symbol值是否在全局登记过,返回key或者undefined
let sy1=Symbol('one')
let sy2=Symbol('two')
console.log(sy1,sy2);
console.log(sy1===sy2);
//Symbol(one) Symbol(two)
//false
let sy3=Symbol.for('two')
let sy4=Symbol.for('two')
console.log(sy3,sy4);
console.log(sy3===sy4);
//Symbol(two) Symbol(two)
//true
console.log(Symbol.keyFor(sy1));
console.log(Symbol.keyFor(sy2));
console.log(Symbol.keyFor(sy3));
console.log(Symbol.keyFor(sy4));
//Symbol(one) Symbol(two)
//false
//Symbol(two) Symbol(two)
//true
//undefined
//undefined
//two
//two
4)应用:消除魔术字符串
魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。
风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。