摘要:声明和定义声明一个构造函数声明一个类以上两者相比之下,很可以看出,类函数比构造函数,代码量更少,并且结构层次更加简洁明了。类主要内容是构造函数静态方法继承。构造函数一个类里,必有一个函数,默认。
ES6 Class类
ES6中class是基于原型的继承的语法糖,提供更加清晰的语法来创建对象和原型。声明和定义
es5 声明一个构造函数:
function Student(name, age) { this.name = name; this.age = age; } Student.prototype.getInfo = function() { return "{name:" + this.name + ",age:" + this.age + "}"; } Student.prototype.setInfo = function(name, age) { this.name = name; this.age = age; } var p = new Student("nico", 1); p.getInfo(); //{name:nico,age:1} p.setInfo("siip", 10); p.getInfo(); //{name:siip,10}
es6 声明一个类:
class Student { constructor(name, age) { this.name = name; this.age = age; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } let p = new Student("nico", 1); p.setInfo("siip", 10); p.getInfo();//{name:siip,10}
以上两者相比之下,很可以看出,es6类函数比es5构造函数,代码量更少,并且结构层次更加简洁明了。
有些地方需要注意的是:
es5存在变量提升(var xxx,function xxx(){})
es6不存在变量提升(const,let,class)
Class 方法constructor
constructor是默认的方法,就算在声明类函数时没有写constructor方法,在实例化时会自动添加上一个空的constructor
class Student { constructor() { this.desc = "test"; } }
通过babel转码:
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Student = function Student() { _classCallCheck(this, Student);//类不能直接被调用,只能通过new实例化 this.desc = "test"; };
constructor方法指向自身,在一个类中只能有一个名为 “constructor” 的特殊方法。
Student === Student.prototype.constructor;//true
static
简述:顾名思义这是一个静态方法,就是不需要实例化类就可以调用的方法, 实例化对象不能继承静态方法。
class Student { constructor(name, age) { this.name = name; this.age = age; } static ageFilter(...args) { let stuAge = args; let arr = []; for (let i = 0; i < stuAge.length; i++) { if (stuAge[i].age > 12) { arr.push(stuAge[i]) } } return arr; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } Student.ageFilter({ name: "a", age: 1 }, { name: "b", age: 14 });//{name: "a", age: 14}
静态函数的this指向类函数自身,当this没有指明被谁调用时,this为undefined
我们将上面代码用babel编译,从结果上看:
var _createClass = function() { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function(Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
从代码可以看出,静态方法与类函数方法的区别是:当用Object.defineProperty去定义对象属性时传入的对象不同,一个传入的是构造函数的原型,另一个是传入构造函数。
es6当前还不支持静态属性
extends
关键字在类声明或类表达式中用于创建一个类作为另一个类的一个子类
class Student { constructor(name = null, age = null) { this.name = name; this.age = age; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } class Citizen extends Student { constructor(name, age) { super(name, age); this.name = 123; } } let stu = new Citizen("siip", "25"); stu.getInfo(); //{name:siip,age:25}
可以看到子类可以调用父类上的方法和属性,当使用extends继承父类时,子类constructor和super和被默认添加上,并且在构造函数内,只有调用了super函数后才能使用this,否则会抛出ReferenceError错误
constructor() { this.name = "xxx" super() }//ReferenceError
super
super可作为一个函数使用
super可作为一个对象使用
下面一个子类继承父类的Math的方法:
function MathFns() { this.status = "Father" } MathFns.prototype = Math; class Max extends MathFns { constructor() { super(); } static base() { return super.max(); } } let m = new MathFns(); m; //{status: "Father"} m.max(1, 2);//2
我们可以通过babel编译,尝试去理解es6的继承,
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
这个封装继承函数,主要实现的功能是,子类原型指向父类,原型构造器指向自身,然后再通过隐式原型链指向父类函数,这样子类被实例化后的对像就能使用父类原型链上的方法以及通过隐式原型链访问到父类的属性。
总结总的来看,es6的class类实际上是基于原型链和继承做的一层封装,它的结构层次相对于es5原型链写法更加清晰明了,代码量更少。class类主要内容是构造函数、静态方法、继承。
构造函数
一个类里,必有一个constructor函数,默认。
类不存在变量提升
一个类里只能有一个constructor函数
constructor函数指向类自身
静态方法
静态函数的this指向类函数自身,当this没有指明被谁调用时,this为undefined
在同一个类中的一个静态方法调用另一个静态方法
类实例化对象不能调用类静态方法
继承
子类继承父类的属性和方法
在子类继承父类,子类的构造函数中要先调用super函数,才能使用this
super可以作为函数或对象调用,但指向都是子类
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/107354.html
摘要:的类使用熟悉的关键字指定类继承的函数,并且可以通过方法访问父类的构造函数。例如继承一个的类继承了,术语上称为基类,为派生类。例如注意到上例中,不仅是派生类的实例,也是派生类的实例,内建对象继承的实用之处是改变返回对象的类型。 和其它面向对象编程语言一样,ES6 正式定义了 class 类以及 extend 继承语法糖,并且支持静态、派生、抽象、迭代、单例等,而且根据 ES6 的新特性衍...
摘要:不同于其他面向对象语言,以前的中中没有类的概念,主要是通过原型的方式来实现继承,中引入了原型链,并且将原型链用来实现继承,其核心是利用原型使得一个对象继承另一个对象的方法和属性,中原型继承的关键是将一个实例的原型对象指向另一个实例,因此前一 不同于其他面向对象语言,ES6以前的JavaScript中中没有class类的概念,主要是通过原型的方式来实现继承,JavaScript中引入了原...
摘要:使用类创建实例对象也是直接对类使用命令,跟中构造函数的用法一致。中没有构造函数,作为构造函数的语法糖,同时有属性和属性,因此同时存在两条继承链。子类的属性,表示构造函数的继承,总是指向父类。 1 Class in ES6 ES6提出了类(Class)的概念,让对象的原型的写法更像面向对象语言写法。 ES6中通过class定义对象,默认具有constructor方法和自定义方法,但是包含...
摘要:使用类创建实例对象也是直接对类使用命令,跟中构造函数的用法一致。中没有构造函数,作为构造函数的语法糖,同时有属性和属性,因此同时存在两条继承链。子类的属性,表示构造函数的继承,总是指向父类。 1 Class in ES6 ES6提出了类(Class)的概念,让对象的原型的写法更像面向对象语言写法。 ES6中通过class定义对象,默认具有constructor方法和自定义方法,但是包含...
阅读 1012·2021-11-22 13:52
阅读 1448·2021-11-19 09:40
阅读 3170·2021-11-16 11:44
阅读 1274·2021-11-15 11:39
阅读 3906·2021-10-08 10:04
阅读 5363·2021-09-22 14:57
阅读 3103·2021-09-10 10:50
阅读 3186·2021-08-17 10:13