JavaScript ES6中CLASS的使用详解


Posted in Javascript onNovember 22, 2016

前言

对于javascript来说,类是一种可选(而不是必须)的设计模式,而且在JavaScript这样的[[Prototype]] 语言中实现类是很蹩脚的。

这种蹩脚的感觉不只是来源于语法,虽然语法是很重要的原因。js里面有许多语法的缺点:繁琐杂乱的.prototype 引用、试图调用原型链上层同名函数时的显式伪多态以及不可靠、不美观而且容易被误解成“构造函数”的.constructor。

除此之外,类设计其实还存在更进一步的问题。传统面向类的语言中父类和子类、子类和实例之间其实是复制操作,但是在[[Prototype]] 中并没有复制。

对象关联代码和行为委托使用了[[Prototype]] 而不是将它藏起来,对比其简洁性可以看出,类并不适用于JavaScript。

ES6中CLASS的使用

javascript传统做法是当生成一个对象实例,需要定义构造函数,然后通过new的方式完成。

function StdInfo(){
  this.name = "job";      
  this.age = 30;      
}

StdInfo.prototype.getNames = function (){
  console.log("name:"+this.name);        
}
//得到一个学员信息对象
var p = new StdInfo()

javacript中只有对象,没有类。它是是基于原型的语言,原型对象是新对象的模板,它将自身的属性共享给新对象。这样的写法和传统面向对象语言差异很大,很容易让新手感到困惑。

定义类

到了ES6添加了类,作为对象的模板。通过class来定义一个类:

//定义类
class StdInfo {
  constructor(){
    this.name = "job";      
    this.age = 30;   
  }
  //定义在类中的方法不需要添加function
  getNames(){
    console.log("name:"+this.name);   
  }
}
//使用new的方式得到一个实例对象
var p = new StdInfo();

上面的写法更加清晰、更像面向对象编程的语法,看起来也更容易理解。

定义的类只是语法糖,目的是让我们用更简洁明了的语法创建对象及处理相关的继承。

//定义类
class StdInfo {
  //...
}
console.log(typeof StdInfo); //function

console.log(StdInfo === StdInfo.prototype.constructor); //true

从上面的测试中可以看出来,类的类型就是一个函数,是一个“特殊函数”,指向的是构造函数。

函数的定义方式有函数声明和函数表达式两种,类的定义方式也有两种,分别是:类声明和类表达式。

类声明

类声明是定义类的一种方式,使用关键字class,后面跟上类名,然后就是一对大括号。把这一类需要定义的方法放在大括号中。

//定义类,可以省略constructor
class StdInfo {
  getNames(){
    console.log("name:"+this.name);
  }
}
// -------------------------------------
//定义类,加上constructor
class StdInfo {
  //使用new定义实例对象时,自动调用这个函数,传入参数
  constructor(name,age){
    this.name = name;      
    this.age = age;   
  }
  
  getNames(){
    console.log("name:"+this.name);   
  }
}
//定义实例对象时,传入参数
var p = new StdInfo("job",30)

constructor是一个默认方法,使用new来定义实例对象时,自动执行constructor函数,传入所需要的参数,执行完constructor后自动返回实例对象。

一个类中只能有一个constructor函数,定义多个会报错。

constructor中的this指向新创建的实例对象,利用this往新创建的实例对象扩展属性。

在定义实例对象时,不需要在初始化阶段做一些事,可以不用显示的写constructor函数。如果没有显式定义,一个空的constructor方法会被默认添加,constructor(){}

类表达式

类表达式是定义类的另一种形式,类似于函数表达式,把一个函数作为值赋给变量。可以把定义的类赋值给一个变量,这时候变量就为类名。class关键字之后的类名可有可无,如果存在,则只能在类内部使用。

定义类 class后面有类名:

const People = class StdInfo {
  constructor(){
    console.log(StdInfo); //可以打印出值,是一个函数
  }
}

new People();
new StdInfo(); //报错,StdInfo is not defined;

定义类 class后面没有类名:

const People = class {
  constructor(){

  }
}

new People();

立即执行的类:

const p = new class {
  constructor(name,age){
    console.log(name,age);
  }
}("job",30)

立即执行的类,在类前要加上new。p为类的实例对象。

不存在变量提升

定义类不存在变量提升,只能先定义类后使用,跟函数声明有区别的。

//-----函数声明-------
//定义前可以先使用,因为函数声明提升的缘故,调用合法。
func();
function func(){}

//-----定义类---------------
new StdInfo(); //报错,StdInfo is not defined
class StdInfo{}

EXTENDS继承

使用extends关键字实现类之间的继承。这比在ES5中使用继承要方便很多。

//定义类父类
class Parent {
  constructor(name,age){
    this.name = name;
    this.age = age;
  }

  speakSometing(){
    console.log("I can speek chinese");
  }
}
//定义子类,继承父类
class Child extends Parent {
  coding(){
    console.log("coding javascript");
  }
}

var c = new Child();

//可以调用父类的方法
c.speakSometing(); // I can speek chinese

使用继承的方式,子类就拥有了父类的方法。

如果子类中有constructor构造函数,则必须使用调用super。

//定义类父类
class Parent {
  constructor(name,age){
    this.name = name;
    this.age = age;
  }

  speakSometing(){
    console.log("I can speek chinese");
  }
}
//定义子类,继承父类
class Child extends Parent {
  constructor(name,age){
    //不调super(),则会报错 this is not defined

    //必须调用super
    super(name,age);
  }

  coding(){
    console.log("coding javascript");
  }
}

var c = new Child("job",30);

//可以调用父类的方法
c.speakSometing(); // I can speek chinese

子类必须在constructor方法中调用super方法,否则新建实例时会报错(this is not defined)。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

总结

好了,以上就是对ES6中类的简单总结学习,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript表单验证 - Parsley.js使用和配置
Jan 25 Javascript
IE8下String的Trim()方法失效的解决方法
Nov 08 Javascript
javascript中的循环语句for语句深入理解
Apr 04 Javascript
jQuery固定元素插件scrolltofixed使用指南
Apr 21 Javascript
浅谈JavaScript中null和undefined
Jul 09 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
Nov 24 Javascript
AngularJS数据源的多种获取方式汇总
Feb 02 Javascript
使用jQuery.form.js/springmvc框架实现文件上传功能
May 12 Javascript
JavaScript设置名字输入不合法的实现方法
May 23 Javascript
利用js给datalist或select动态添加option选项的方法
Jan 25 Javascript
浅谈vue单一组件下动态修改数据时的全部重渲染
Mar 01 Javascript
vue如何实现关闭对话框后刷新列表
Apr 08 Vue.js
AngularJS实现ajax请求的方法
Nov 22 #Javascript
js数组操作方法总结(必看篇)
Nov 22 #Javascript
jQ处理xml文件和xml字符串的方法(详解)
Nov 22 #Javascript
js字符串操作总结(必看篇)
Nov 22 #Javascript
JavaScript的兼容性与调试技巧
Nov 22 #Javascript
关于Iframe父页面与子页面之间的相互调用
Nov 22 #Javascript
JS中BOM相关知识点总结(必看篇)
Nov 22 #Javascript
You might like
PHP iconv 函数转gb2312的bug解决方法
2009/10/11 PHP
php中实现记住密码自动登录的代码
2011/03/02 PHP
php写的带缓存数据功能的mysqli类
2012/09/06 PHP
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
php中字符串和正则表达式详解
2014/10/23 PHP
PHP数据库连接mysql与mysqli对比分析
2016/01/04 PHP
Laravel搭建后台登录系统步骤详解
2016/07/26 PHP
php加速缓存器opcache,apc,xcache,eAccelerator原理与配置方法实例分析
2020/03/02 PHP
基于Asp.net与Javascript控制的日期控件
2010/05/22 Javascript
基于jQuery的图片剪切插件
2011/08/03 Javascript
禁止拷贝网页内容的js代码
2014/01/22 Javascript
javascript 常见功能汇总
2015/06/11 Javascript
Highcharts使用简例及异步动态读取数据
2015/12/30 Javascript
AngularJS入门教程之多视图切换用法示例
2016/11/02 Javascript
bootstrap select插件封装成Vue2.0组件
2017/04/17 Javascript
Vue2.0 组件传值通讯的示例代码
2017/08/01 Javascript
随机生成10个不重复的0-100的数字(实例讲解)
2017/08/16 Javascript
Vue最新防抖方案(必看篇)
2019/10/30 Javascript
jQuery事件模型默认行为执行顺序及trigger()与 triggerHandler()比较实例分析
2020/04/30 jQuery
解决vue+router路由跳转不起作用的一项原因
2020/07/19 Javascript
跟老齐学Python之开始真正编程
2014/09/12 Python
Python3简单实例计算同花的概率代码
2017/12/06 Python
Python cookbook(数据结构与算法)根据字段将记录分组操作示例
2018/03/19 Python
numpy中实现ndarray数组返回符合特定条件的索引方法
2018/04/17 Python
解决python爬虫中有中文的url问题
2018/05/11 Python
详解Python3注释知识点
2019/02/19 Python
python3实现高效的端口扫描
2019/08/31 Python
wxPython实现列表增删改查功能
2019/11/19 Python
Python实现LR1文法的完整实例代码
2020/10/25 Python
非常漂亮的CSS3百叶窗焦点图动画
2016/02/24 HTML / CSS
html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
2013/01/09 HTML / CSS
驴妈妈旅游网:中国新型的B2C旅游电子商务网站
2016/08/16 全球购物
设备售后服务承诺书
2014/05/30 职场文书
2015年安全生产月活动总结
2015/03/26 职场文书
郭明义电影观后感
2015/06/08 职场文书
WCG2010 星际争霸决赛 Flash vs Goojila 1 星际经典比赛回顾
2022/04/01 星际争霸