es6笔记7^_^class
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。 部分来自JavaScript ES6 class指南、mozilla https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes
1.定义类
让我们回想一下在ES5中定义一个类的方式。通过不是很常用的Object.defineProperty方法,我可以定义一些只读的属性。
function Vehicle1(make, year) {
Object.defineProperty(this, 'make', {
get: function() { return make; }
});
Object.defineProperty(this, 'year', {
get: function() { return year; }
});
}
Vehicle1.prototype.toString = function() {
return this.make + ' ' + this.year;
}
var vehicle1 = new Vehicle1('Toyota Corolla', 2009);
console.log(vehicle1.make); // Toyota Corolla
vehicle1.make = 'Ford Mustang';
console.log(vehicle1.toString()) // Toyota Corolla 2009
很简单,我们定义了一个有两个只读属性和一个自定义toString方法的Vehicle类。让我们在ES6中来做一样的事情:
class Vehicle {
constructor(make, year) {
this._make = make;
this._year = year;
}
get make() {
return this._make;
}
get year() {
return this._year;
}
toString() {
return `${this.make} ${this.year}`;
}
}
var vehicle = new Vehicle('Toyota Corolla', 2009);
console.log(vehicle.make); // Toyota Corolla
vehicle.make = 'Ford Mustang';
console.log(vehicle.toString()) // Toyota Corolla 2009
上面两个例子中定义的类有一个不同的地方。我们为了享受新的get语法带来的好处,所以只是将make和year定义成了普通的属性。这使它们可以被外部所改变。如果你确实需要一个严格的私有属性,还是请继续使用defineProperty。
2.类声明
类声明是定义类的一种方式,就像下面这样,使用 class 关键字后跟一个类名(这里是 Polygon),就可以定义一个类。
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
3.变量提升
类声明和函数声明不同的一点是,函数声明存在变量提升现象,而类声明不会。
也就是说,你必须先声明类,然后才能使用它,否则代码会抛出 ReferenceError 异常,像下面这样:
var p = new Polygon(); // ReferenceError
class Polygon {}
4.类表达式
类表达式是定义类的另外一种方式。在类表达式中,类名是可有可无的。如果定义了类名,则该类名只有在类体内部才能访问到。
匿名的
var Polygon1 = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
命名的
var Polygon2 = class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
注意: 类表达式和类声明一样也不会有提升的现象。
5.原型方法
class Polygon3 {
constructor(height, width) {
this.height = height;
this.width = width;
}
get area() {
return this.calcArea()
}
calcArea() {
return this.height * this.width;
}
}
const square = new Polygon3(10, 10);
console.log(square.area);//
6.静态方法
static 关键字用来定义类的静态方法。静态方法是指那些不需要对类进行实例化,使用类名就可以直接访问的方法,需要注意的是静态方法不能被实例化的对象调用。静态方法经常用来作为工具函数。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.sqrt(dx*dx + dy*dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
console.log(Point.distance(p1, p2));
7.类继承
使用 extends 创建子类
extends 关键字可以用在类声明或者类表达式中来创建一个继承了某个类的子类。
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
var d = new Dog('Mitzie');
d.speak();// 'Mitzie barks.'
//同样也可以用于原有的原型继承的“类”:
function Animal2 (name) {
this.name = name;
}
Animal2.prototype.speak = function () {
console.log(this.name + ' makes a noise.');
}
class Dog2 extends Animal2 {
speak() {
super.speak();
console.log(this.name + ' barks.');
}
}
var d2 = new Dog2('Mitzie');
d2.speak();
//需要注意的是类不能继承一般(非构造的)对象。如果你想要创建的类继承某个一般对象的话,你要使用 Object.setPrototypeOf():
var Animal3 = {
speak() {
console.log(this.name + ' makes a noise.');
}
};
class Dog3 {
constructor(name) {
this.name = name;
}
speak() {
super.speak();
console.log(this.name + ' barks.');
}
}
Object.setPrototypeOf(Dog3.prototype, Animal3);
var d3 = new Dog3('Mitzie');
d3.speak();
8.Species
你可能想要数组类 MyArray 返回的是 Array 对象。这个 species 模式能让你重写默认的构造器。
例如,当使用像 map() 这样的方法来返回默认的构造器时,你想要这个方法返回父级的 Array 对象,而不是 MyArray 对象。Symbol.species 能实现:
class MyArray extends Array {
// Overwrite species to the parent Array constructor
static get [Symbol.species]() { return Array; }
}
var a = new MyArray(1,2,3);
var mapped = a.map(x => x * x);
console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array); // true
9.super 关键字可以用来调用其父类的构造器或者类方法
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(this.name + ' roars.');
}
}
new Lion('nick').speak();
//再看个重要的例子
class Animal4 {
constructor(){
this.type = 'animal';
}
says(say){
console.log(this.type + ' says ' + say);
}
}
let animal4 = new Animal4();
animal4.says('hello') //animal says hello
class Cat4 extends Animal4 {
constructor(){
super();
this.type = 'cat';
// 1.子类定义constructor;
// 2.调用super();
// 3.this就会指向子类实例cat4,否则constructor内this报错或子类方法内this指向父类实例
}
}
let cat4 = new Cat4();
cat4.says('hello'); //cat says hello
上面代码首先用class定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。
简单地说,constructor内定义的方法和属性是实例对象自己的,而constructor外定义的方法和属性则是所有实例对象可以共享的。
Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。
上面定义了一个Cat类,该类通过extends关键字,继承了Animal类的所有属性和方法。
super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,否则新建实例时会报错。
这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
ES6的继承机制,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。
es6暂终
es6笔记7^_^class的更多相关文章
- ES6笔记(5)-- Generator生成器函数
系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...
- ES6笔记系列
ES6,即ECMAScript 6.0,ES6的第一个版本是在2015年发布的,所以又称作ECMAScript 2015 如今距ES6发布已经一年多的时间,这时候才去学,作为一个JSer,羞愧羞愧,还 ...
- ES6笔记(1) -- 环境配置支持
系列文章 -- ES6笔记系列 虽然ES6已经发布一年多了,但在各大浏览器之中的支持度还不是很理想,在这查看ES6新特性支持度 Chrome的最新版本浏览器大部分已经支持,在Node.js环境上支持度 ...
- ES6笔记(2)-- let的块级作用域
系列文章 -- ES6笔记系列 一.函数级作用域 我们都知道,在ES6以前,JS只有函数级作用域,没有块级作用域这个概念 没有块级作用域,有利有弊,利于方便自由,弊于作用域内的变量容易被共享,例如这个 ...
- ES6笔记(3)-- 解构赋值
系列文章 -- ES6笔记系列 解构赋值,即对某种结构进行解析,然后将解析出来的值赋值给相关的变量,常见的有数组.对象.字符串的解构赋值等 一.数组的解构赋值 function ids() { ret ...
- ES6笔记(4)-- Symbol类型
系列文章 -- ES6笔记系列 Symbol是什么?中文意思是标志.记号,顾名思义,它可以用了做记号. 是的,它是一种标记的方法,被ES6引入作为一种新的数据类型,表示独一无二的值. 由此,JS的数据 ...
- ES6笔记(6)-- Set、Map结构和Iterator迭代器
系列文章 -- ES6笔记系列 搞ES6的人也是够无聊,把JS弄得越来越像Java.C++,连Iterator迭代器.Set集合.Map结构都出来了,不知道说什么好... 一.简单使用 1. iter ...
- ES6笔记(7)-- Promise异步编程
系列文章 -- ES6笔记系列 很久很久以前,在做Node.js聊天室,使用MongoDB数据服务的时候就遇到了多重回调嵌套导致代码混乱的问题. JS异步编程有利有弊,Promise的出现,改善了这一 ...
- ES6 笔记汇总
ES6 笔记汇总 二.ES6基础-let和const命令 三.变量的解构赋值 四.字符串的拓展 五.正则表达式的拓展 ...将会持续更新,敬请期待
- ES6笔记2
ES6笔记2 Promise Promise 是 ES6 引入的异步编程的新解决方案,语法上是一个构造函数 一共有3种状态,pending(进行中).fulfilled(已成功)和rejected(已 ...
随机推荐
- 把中文版NetBeans改成英文版
不管你从官网下的是英文版还是中文版,安装之后操作界面都是中文的.这是因为NetBeans会根据你的操作系统自动设置界面语言,并且没有提供更改的功能.解决的方法也很简单,下面介绍我用过的两种方法: 方法 ...
- xtrabackup数据库备份
xtrabackup备份 一.Xtrabackup概述 1.1.简介 Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Ho ...
- (简单) CF 44D Hyperdrive,数学。
In a far away galaxy there are n inhabited planets, numbered with numbers from 1 to n. They are loca ...
- 使用PHPmailer 发送邮件,使用QQ smtp服务器
<meta charset="utf-8"> <?php include("class.phpmailer.php"); include(&q ...
- HttpServletRequest.getServletContext()一直提示找不到,而引出的问题
开发j2ee项目的时候,需要用到servlet-api,如果使用了maven,web项目可以在pom.xml中手动加入所需jar包,达到与依赖j2ee libarary同样的功能.可问题来了: 1. ...
- iOS之NSPredicate(正则表达式和UIBarController)
本文转发至:https://segmentfault.com/a/1190000000623005 NSPredicate,这个类和我上一篇博文中提到的valueForKeyPath一样很强大.它的使 ...
- createNewFile()与createTempFile()的不同
1, File 的 createNewFile() 方法: createNewFile():返回值为 boolean: 方法介绍:当且仅当不存在具有此抽象路径名指定名称的文件时, ...
- jquery 如何动态添加、删除class样式方法介绍_jquery_脚本之家
获取与设置样式 获取class和设置class都可以使用attr()方法来完成.例如使用attr()方法来获取p元素的class 取与设置样式 获取class和设置class都可以使用attr()方法 ...
- mysql优化----第一篇:综述
一 系统层面 查看CPU和IO状态,确定瓶颈.增 更换设备 二 数据库层面 1 参数优化. 参考文章<mysql性能优化----调整参数>增大数据库内存缓存等设置. 参考 http: ...
- iOS8学习笔记2--autolayout
iOS支持的设备如今已经具有了很多的尺寸,针对这些不同的尺寸每一个都做一个独立的APP肯定是不现实的,于是苹果在iOS8之后推出了autolayout和sizeclass,同时还有VFL界面设计语言 ...