ES6 之 类与继承

ES6的类与继承与ES5的类与继承相比较

class 类

创建一个Animal

ES6
  • ES6中类的创建变得非常简单
class Animal {}

注:class中的静态变量可以被枚举,function中的静态变量不可以被枚举。方法都不可以被枚举.
class创建的构造函数的原型里的方法是不能被实例枚举,但function可以。属性都可以枚举。

ES5
function Animal() {}

constructor 构造器

新的构造器,为Animal类加上species构造属性

ES6
class Animal {
	constructor(species){
		this.species = species
	}
}
ES5
function Animal() {
	this.species = species
}

为原型加上方法

Animal的原型加上eat方法

ES6
class Animal {
	constructor(species){
		this.species = species
	}
	eat(){//直接在class中写,将class看成function就行,里面的方法可以省略function
		console.log('eateat')
	}
}
ES5
function Animal(species) {
	this.species = species
}
Animal.prototype.eat = function() { console.log('eateat') }

static 静态方法

Animal类加上isAnimal静态方法

ES6
class Animal {
	constructor(species){
		this.species = species
	}
	eat() {
		console.log('eateat')
	}
	static isAnimal() {//静态方法需要 static 修饰
		console.log('i don\'t know ')
	}
}
ES5
function Animal(species) {
	this.species = species
	function isAnimal() {//加上静态方法
		console.log('i don\'t know ')
	}
}
Animal.prototype.eat = function() { console.log('eateat') }

extends 和 super

创建Lion类继承于Animal

ES6
class Animal {
	constructor(species){
		this.species = species
	}
	eat() {
		console.log('eateat')
	}
	static isAnimal() {
		console.log('i don\'t know ')
	}
}
class Lion extends Animal{//创建Lion类
	constructor(species, size){
		super(species)//继承父类的属性,必须写在任何this的开头,不然会报错
		this.size = size
	}
	eat() {//重写原型方法
		console.log('eatmeat')
	}
}
let lion = new Lion('Feline family','big')
ES5
//创建Animal类
function Animal(species) {
	this.species = species
}
Animal.isAnimal() {
	console.log('i don\'t know ')
}
Animal.prototype.eat = function() { console.log('eateat') }
//创建Lion类继承自Animal类
function Lion(species, size) {
	Animal.call(this,species)//继承属性
	this.size = size
}
Lion.__proto__ = Animal
//创建一个原型是Animal的原型的对象作为Lion的原型,extends干的事
Lion.prototype = Object.create(Animal.prototype)
Lion.prototype.conostructor = Lion
//重写eat方法
Lion.prototype.eat = function() { console.log('eat meat') }
//实例化对象
let lion = new Lion('Feline family','big')

注:为什么不用Object.setPrototype,在MDN上是这么说的

警告: 由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]在各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.proto = … 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果你关心性能,你应该避免设置一个对象的 [[Prototype]]。相反,你应该使用 Object.create()来创建带有你想要的[[Prototype]]的新对象。

翻译成人话就是更改一个对象的原型比创建一个带有相应原型的对象性能上更差,具体为什么性能更差,有没有大佬说说。

最后就写一个_new方法实现new的功能吧。
new的功能

  • 实例化类
  • 继承类的原型
//传入需要实例化的类和实例化需要的参数,因为不确定参数个数,所以用`...`可变参数
function _new(cons, ...param) {
  //创建绑定构造函数对象的原型的对象
  let obj = Object.create(_class.prototype)
  //执行构造函数
  let result = cons.apply(obj, param)
  //返回对象,如果构造函数 return 了一个对象,则返回构造函数 return 的
  return result instanceof Object ? result : obj
}

如果传的参数个数为0个,params会变成空数组,传入apply,apply会将数组中的值依次传入,空数组会传undefined,和不传params一样,会赋值undefined,和new一样。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值