ES6类-继承-Symbol-模版字符串

目录

 继承

ES5 如何继承

ES6继承

Symbol

用途

可以产生唯一的值,独一无二的值

解决命名冲突

getOwnPropertySymbols()

 作为全局注册表 缓存  Symbol.for()

 消除魔术字符串

 模版字符串


在javascript语言中,生成实例对象使用构造函数;ES6提供了类Class这个概念,作为对象的模板。定义一个类通过class关键字,ES6的类可以看成是构造函数的另一种写法。

class Person{
    constructor(name,age,gender){
        // 类构造器中属性和方法是实例私有属性和私有方法
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    // 实例公共方法 类似于存放在Person类原型对象中
    sayName(){
        console.log(this.name);
    }
    test = 'hello'; //实例公共属性
    friends = [];  //实例私有属性
    // 类静态属性和静态方法
    static personAttr = '类的静态属性';
    static personMethod = function(){
        console.log('类静态方法this指向类本身');
        console.log(this,this.personAttr,this.test,this.friends);
    }
}
let p1 = new Person('可乐',12,'male');
let p2 = new Person();
console.log(p1.test,p2.test);
console.log(p1.test === p2.test);
p1.friends.push('tom');
console.log(p1.friends,p2.friends);
console.log(p1.friends === p2.friends);
Person.personMethod();

 继承

ES5 如何继承

实例使用属性和方法
  1.从实例对象本身查找属性或者方法
  2.如果实例没有,从构造函数的原型对象中找
  3.如果还没有,从父构造函数的原型对象中找

/**
 * es5 继承 
 * 经典继承 原型链继承
 */
// function Animal(name,age,length,weight){
// 	this.name = name;
// 	this.age = age;
// 	this.length = length;
// 	this.weight = weight;
// }
// Animal.prototype = {
// 	constructor:Animal,
// 	sayType(){
// 		console.log(this.type)
// 	}
// }
// function Dog(name,age,length,weight,type){
// 	// 继承父构造函数属性  借用构造函数继承 经典继承
// 	Animal.call(this,name,age,length,weight);
// 	this.type = type;
// }
// // 原型链继承 子类得原型对象指向父类得实例 
// Dog.prototype = new Animal();
// Dog.prototype.constructor = Dog;
// let d1 = new Dog('可乐',12,'40cm','10kg','狗');
// d1.sayType();
// console.log(d1);

更详细的ES5继承见面向对象之创建对象模式和继承模式_学前端的狗头苏丹的博客-CSDN博客

ES6继承

class可以通过extends关键字实现继承,子类可以没有构造函数,系统会默认分配。子类提供了构造函数则必须要显式调用super。super函数类似于借用构造函数。类似于Animal.call()

1.子类对象指向父类对象

2.子类原型对象继承父类原型对象

/**
 * ES6继承 使用extends关键字实现继承
 */
class Animal{
    // 构造器属性 实例私有属性
    constructor(name,age,length){
        this.name = name;
        this.age = age;
        this.length = length;
    }
    // 类体方法 实例公共方法  存放在Animal.prototype中
    sayName(){
        console.log(this.name);
    }
    test = 'hello';
    friends = [];
    // 静态属性和静态方法
    static ParentAttr = '父类属性';
    static ParentMethod = function(a){
        console.log('父类的方法');
        return a instanceof Animal;
    }
}
// 子类继承父类     不提供constructor的情况
class Dog extends Animal{

}
let d1 = new Dog('可乐',12,'50cm');
console.log(d1);
d1.sayName();
d1.friends.push('tom')
console.log(d1.test,d1.friends,d1);
console.log(Dog.ParentAttr);
console.log(Dog.ParentMethod(d1));

// 子类继承自父类
console.log(Dog.__proto__ === Animal);
// 子类原型对象继承自父类的原型对象
console.log(Dog.prototype.__proto__ === Animal.prototype);

// 子类如果提供了构造器 必须显示调用super
// class Dog2 extends Animal{
//     constructor(name,age,weight,type,color){
//         super(name,age,weight); //相当于调用父类构造器  Animal.call()
//         this.type = type;
//         this.color = color;
//     }
//     sayName(){
//         console.log(this.name,'子类实例公共方法');
//     }
// }
// let d2 = new Dog2('可乐',12,'50cm','狗','黑色');
// console.log(d2);
// d2.sayName();

Symbol

ES6引入的一种新的原始数据类型Symbol,表示独一无二的值。Symbol函数可以接受参数,表示对于这个唯一值的描述。属于基本数据类型,Symbol()函数会返回symbol类型的值

参数:字符串 表示对这个symbol值的描述

用途

可以产生唯一的值,独一无二的值
let sy1 = Symbol();
let sy2 = Symbol();
console.log(sy1,sy2,sy1 === sy2,sy1.toString());

let a = new Number();
let b = new String();
console.log(a,b);

解决命名冲突
let sy3 = Symbol('name'); //接收的字符串 对symbol的描述
let sy4 = Symbol('age');
let obj = {
    name:'zhangsan',
    age:12,
    [sy3]:'terry',
    [sy4]:18,
    [Symbol('email')]:"[email protected]"
}
console.log(obj);
for(let key in obj){
    console.log(key);
}

 

getOwnPropertySymbols()

 从上图输出结果来看:我们可以发现for in循环无法遍历到symbol值作为属性名对应的属性,我们想要获取所有的symbol值对应的属性,,则需要使用getOwnPropertySymbols()方法

/**
 * 获取所有的symbol值对应的属性
 * getOwnPropertySymbols
 */
console.log(Object.getOwnPropertySymbols(obj));
let s = Object.getOwnPropertySymbols(obj);  //[ Symbol(name), Symbol(age), Symbol(email) ]
console.log(obj[s[2]]);

 

 作为全局注册表 缓存  Symbol.for()

全局注册表
Symbol() 不同的是,用 Symbol.for() 方法创建的的 symbol 会被放入一个全局 symbol 注册表中。Symbol.for() 并不是每次都会创建一个新的 symbol,它会首先检查给定的 key 是否已经在注册表中了。假如是,则会直接返回上次存储的那个。否则,它会再新建一个。

/**
 * 3.作为全局注册表 缓存 Symbol.for()
 */
// 将symbol放到全局注册表中
let sy5 = Symbol.for('hello');
let sy6 = Symbol.for('hello');
console.log(sy5 === sy6);       //true

// 每次都会创建一个不同symbol值  虽然描述符一样 但是Symbol value值不一样
let sy7 = Symbol('hello');
let sy8 = Symbol('hello');
console.log(sy7 === sy8);       //false

// Symbol.keyFor()可以检测symbol值是否在全局注册表中注册过。 返回对于symbol的描述或者undefined
console.log(Symbol.keyFor(sy5));
console.log(Symbol.keyFor(sy6));
console.log(Symbol.keyFor(sy7));

Symbol.keyFor()可以检测symbol值是否在全局注册表中注册过。 返回对于symbol的描述或者undefined 

 消除魔术字符串

魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。

/**
 * 4.消除魔术字符串
 */
function getArea(shape,options){
    let area = 0;
    switch(shape){
        case Shape.SJX:
            area = .5 * options.height * options.width;
            break;
        case Shape.ZFX:
            area = options.height * options.width;
            break;
        case Shape.CIRCLE:
            area = Math.PI * options.r * options.r;
            break;
        default:
            area = -1;
    }
    return area;
}
const Shape = {
    SJX:Symbol('三角形'),
    ZFX:Symbol('正方形'),
    CIRCLE:Symbol('圆'),
}
let res = getArea(Shape.SJX,{height:100,width:100,r:50})
console.log(res);

Shape.SJX = Symbol('六边形');
console.log(Shape);

 模版字符串

模板字面量是用反引号(`)分隔的字面量,允许多行字符串、带嵌入表达式的字符串插值和一种叫带标签的模板的特殊结构。

模板字面量有时被非正式地叫作模板字符串,因为它们最常被用作字符串插值(通过替换占位符来创建字符串)。然而,带标签的模板字面量可能不会产生字符串——它可以与自定义标签函数一起使用,来对模板字面量的不同部分执行任何操作。

/**
 * 模版字符串 可以解析变量
 */
let name = 'zhangsan';
let age = 12;
// let str = 'name' + 'age';
let str = `${name}+${age}`
console.log(str);

let id = 1;
let url = `121.199.0.35:8888/findById?id=${id}`;
console.log(url);

猜你喜欢

转载自blog.csdn.net/qq_53866767/article/details/131743144