ES6之class

ES6中的类

class与构造函数

基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

	//类的写法
	class Point{
	    getName(){
	        return 'lili';
	    }
	}
	
	//构造函数的写法
	function Point2() {}
	Point2.prototype.getName = function () {
	    return 'lili';
	}

其实class也是函数,类里的方法也是定义在prototype上。类的方法都是不可枚举的,通过Object.keys不能获得,但是构造函数原型上的方法可以获得。

类与构造函数对比

// ES6以前的构造函数
	function Person(name, age){
	    this.name = name;
	    this.age = age;
	}
	Person.prototype.eat = function(){
	    return '('+ this.age + '岁的' + this.name +'正在吃饭...'+')';
	}
	p1 = new Person('张三',3);
	p1.eat();
	
	// ES6的构造函数(类)
	class Person{
	    constructor(name, age){
	        this.name = name;
	        this.age = age;
	    }
	    eat(){
	        return '('+ this.age + '岁的' + this.name +'正在吃饭...'+')';
	    }
	}
	let p2 = new Person('张三',3);
	p1.eat();
  • 可以是类在某种意义上就是构造函数的升级版
  • constructor:指向的就是Person类的构造函数(就算你不写,JavaScript引擎也会自动添加一个空的)
  • 在Person类里面编写的方法就是相当于在Person类的原型上编写
  • 类的内部的所有定义的方法,都是不可枚举的
  • 类必须通过new关键字调用,否则会报错

静态方法和静态属性

  • 属于类,不被实例继承,直接通过类来调用。可以被子类继承
  • 内部的this,执行Point本身,而不是实例
  • 可以和非静态方法重名
	class Point {
	    static getX() {
	        this.getY();
	    }
	    static getY(){
	        console.log('y');
	    }
	    getY(){
	        console.log('yy');
	    }
	}
	let point = new Point();
	Point.getX();
	//'y'

私有方法和私有属性

私有方法和私有属性:只能在内部访问,外部不能访问。遗憾的是es6没有面向对象中的私有方法和私有属性

  • 第一种方法:在编程界内部人为规定一个,私有的用"_"开头
  • 第二种方法:Symbol数据类型(但是Reflect.ownKeys可以查看)
const bar = Symbol('bar');
class Point {
	// 私有方法
    [bar](){
        console.log('x')
    }
}

let point = new Point()
console.log(Reflect.ownKeys(Point.prototype));
//[ 'constructor', Symbol(bar) ]

类的取值函数(getter)和存值函数(setter)

	class MyClass {
	  get name() {
	    return 'getter';
	  }
	  set name(value) {
	    console.log('setter: '+value);
	  }
	}
	
	var descriptor = Object.getOwnPropertyDescriptor(
	  CustomHTMLElement.prototype, "name"
	);
  • 类的get和set和以前的构造函数的是一样的
  • 存值函数和取值函数是设置在属性的 Descriptor 对象上的

new.target

new是从构造函数生成实例对象的命令。ES6 为new命令引入了一个new.target属性,该属性一般用在构造函数之中,返回new命令作用于的那个构造函数。如果构造函数不是通过new命令或Reflect.construct()调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的。

	class Point {
	    constructor() {
	        console.log(new.target === Point); //true
	    }
	}
	let point = new Point();

只能在构造函数constructor中使用new.target。其他地方使用会报错

function Point2(name) {
    if (new.target === Point2) {
        this.name = name;
    } else {
        throw new Error('必须使用 new 命令生成实例');
    }
}
let point3 = new Point2('sha');
let point2 = Point2.call({}, 'li'); //抛出异常

类注意点

  • 类的内部默认就是严格模式use strict
  • 类不存在声明提前,有临时性死区
  • this指向会随着调用者改变的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值