ES6中的class创建类
来源:互联网 发布:phantomjs java 编辑:程序博客网 时间:2024/06/09 17:25
转载请注明预见才能遇见的博客:http://my.csdn.net/
原文地址:http://blog.csdn.net/pcaxb/article/details/53759637
ES6 类(Class)基本用法和静态属性+方法详解
JavaScript语言的传统方法是通过构造函数,定义并生成新对象,prototype 属性使您有能力向对象添加属性和方法。下面是通过传统的方式创建和使用对象的案例:
- <span style="font-size:18px;">//Person.js
- function Person(x,y){
- this.x = x;
- this.y = y;
- }
- Person.prototype.toString = function (){
- return (this.x + "的年龄是" +this.y+"岁");
- }
- export {Person};
- //index.js
- import {Person} from './Person';
- let person = new Person('张三',12);
- console.log(person.toString());</span>
1.Class的基本用法
ES6引入了Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用ES6的“类”改写,就是下面这样。
- <span style="font-size:18px;">//Person.js
- class Person{
- // 构造
- constructor(x,y){
- this.x = x;
- this.y = y;
- }
- toString(){
- return (this.x + "的年龄是" +this.y+"岁");
- }
- }
- export {Person};
- //index.js
- import {Person} from './Person';
- let person = new Person('张三',12);
- console.log(person.toString());</span>
ES6的类,完全可以看作构造函数的另一种写法。
- <span style="font-size:18px;">//Person.js
- console.log(typeof Person);//function
- console.log(Person === Person.prototype.constructor);//true</span>
- <span style="font-size:18px;">//Person.js
- console.log(Person.prototype);//输出的是一个对象</span>
- <span style="font-size:18px;">//index.js
- Person.prototype = {
- getName(){
- return '张三';
- },
- getAge(){
- return '12';
- }
- };</span>
- <span style="font-size:18px;">//index.js
- console.log(person.constructor === Person.prototype.constructor);//true</span>
- <span style="font-size:18px;">//index.js
- Object.assign(Person.prototype,{
- getWidth(){
- console.log('12');
- },
- getHeight(){
- console.log('24');
- }
- });
- console.log(Person.prototype);</span>
- <span style="font-size:18px;">//index.js
- //ES5
- console.log(Object.keys(Person.prototype));//["toString", "getWidth", "getHeight"]
- console.log(Object.getOwnPropertyNames(Person.prototype));//["constructor", "toString", "getWidth", "getHeight"]
- //ES6
- console.log(Object.keys(Person.prototype));//["getWidth", "getHeight"]
- console.log(Object.getOwnPropertyNames(Person.prototype));//["constructor", "toString", "getWidth", "getHeight"]</span>
在ES6中,类的属性名可以使用表达式,具体实现方式如下
- <span style="font-size:18px;">//Article.js
- let methodName = "getTitle";
- export default class Article{
- [methodName](){
- console.log('输出文章的标题1');
- }
- }
- //index.js
- import Article from './Article';
- //console.log(Article.prototype);
- let article = new Article();
- article.getTitle()</span>
- <span style="font-size:18px;">//ConstructorStu.js
- import Article from './Article';
- export default class ConstructorStu{
- // 构造
- constructor() {
- console.log('constructor');
- return new Article();
- }
- }
- //index.js
- import ConstructorStu from './ConstructorStu';
- console.log('==111==');
- console.log(new ConstructorStu() instanceof ConstructorStu);//false
- console.log('==222==');
- let cons = new ConstructorStu();
- console.log('==333==');
- cons.constructor();
- console.log('==444==');
- 运行结果
- ==111==
- constructor
- false
- ==222==
- constructor
- ==333==
- ==444==</span>
实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)。hasOwnProperty()函数用于指示一个对象自身(不包括原型链)是否具有指定名称的属性。如果有,返回true,否则返回false。
- <span style="font-size:18px;">//Person.js
- class Person{
- // 构造
- constructor(x,y){
- this.x = x;
- this.y = y;
- }
- toString(){
- return (this.x + "的年龄是" +this.y+"岁");
- }
- }
- let person = new Person('lis',8);
- console.log(person.toString());
- console.log(person.hasOwnProperty('x'));//true
- console.log(person.hasOwnProperty('y'));//true
- console.log(person.hasOwnProperty('toString'));//false
- console.log(person.__proto__.hasOwnProperty('toString'));//true</span>
- <span style="font-size:18px;">let person1 = new Person('张三',12);
- let person2 = new Person('李四',13);
- console.log(person1.__proto__ === person2.__proto__);//true</span>
- <span style="font-size:18px;">let person1 = new Person('张三',12);
- let person2 = new Person('李四',13);
- person1.__proto__.getH = function (){
- return "Height";
- };
- console.log(person1.getH());
- console.log(person2.getH());</span>
__proto__参考资料:点击打开链接
class不存在变量提升,需要先定义再使用,因为ES6不会把类的声明提升到代码头部,但是ES5就不一样,ES5存在变量提升,可以先使用,然后再定义。
- <span style="font-size:18px;">//正确
- new A();
- function A(){
- }//ES5可以先使用再定义,存在变量提升
- //错误
- new B();
- class B{
- }//B is not a constructor
- //ES6不能先使用再定义,不存在变量提升</span>
- <span style="font-size:18px;">//Expression.js
- const Expression = class Expre{
- static getAge(){
- return '12';
- }
- getClassName(){
- return " ClassName1= " +Expre.name + " ClassName2= " +Expression.name;
- }
- };
- let exp = new Expression();
- //let exp = new Expre();错误
- //bundle.js:7935 Uncaught ReferenceError: Expre is not defined
- console.log(exp.getClassName());//ClassName1= Expre ClassName2= Expre
- //console.log(Expre.getAge());错误
- //bundle.js:7935 Uncaught ReferenceError: Expre is not defined
- console.log(Expression.getAge());</span>
如果类的内部没用到的话,可以省略Expre,也就是可以写成下面的形式
- <span style="font-size:18px;">//Expression.js
- const MyExpre = class{
- getClassName(){
- return MyExpre.name;
- }
- };
- let myExpre = new MyExpre();
- console.log(myExpre.getClassName());//MyExpre</span>
采用Class表达式,可以写出立即执行的Class
- <span style="font-size:18px;">//Expression.js
- let person = new class{
- // 构造
- constructor(props) {
- this.props = props;
- }
- getProps(){
- return this.props;
- }
- }('构造函数的参数');
- console.log(person.getProps());//构造函数的参数</span>
私有方法是常见需求,但ES6不提供,只能通过变通方法模拟实现。一种做法是在命名上加以区别,在方法前面加上_(下划线),表示这是一个只限于内部使用的私有方法。但是,这种命名是不保险的,在类的外部,还是可以调用到这个方法。另一种方法就是索性将私有方法移出模块,因为模块内部的所有方法都是对外可见的。
- <span style="font-size:18px;">//PrivateMethod.js
- export default class PrivateMethod{
- // 构造
- constructor() {
- }
- getName(){
- priName();
- }
- }
- function priName(){
- console.log('私有方法测试');
- }
- //index.js
- import PriMe from './PrivateMethod';
- let prime = new PriMe();
- prime.getName();</span>
类的方法内部如果含有this,它默认指向类的实例。getName方法中的this,默认指向ThisStu类的实例。但是,如果将这个方法提取出来单独使用,this会指向该方法运行时所在的环境,因为找不到name方法而导致报错。
- <span style="font-size:18px;">//ThisStu.js
- class ThisStu{
- getName(){
- return this.name();
- }
- name(){
- return '王五';
- }
- }
- export {ThisStu};
- //index.js
- import {ThisStu} from './ThisStu';
- let thisStu = new ThisStu();
- console.log(thisStu.getName());
- const {getName} = thisStu;
- getName();
- //Cannot read property 'name' of undefined</span>
- <span style="font-size:18px;">//ThisStu.js
- class ThisStu{
- // 构造
- constructor() {
- this.getName = this.getName.bind(this);
- }
- getName(){
- return this.name();
- }
- name(){
- return '王五';
- }
- }
- export {ThisStu};</span>
- <span style="font-size:18px;">// 构造
- constructor() {
- //this.getName = this.getName.bind(this);
- this.getName = ()=>{
- return this.name();
- }
- }
- </span>
2.Class的静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
- <span style="font-size:18px;">//StaticMethod.js
- //定义静态方法
- static getAge(){
- return '获取Age的静态方法';
- }
- //通过类名直接调用
- console.log(StaticMethod.getAge());</span>
- <span style="font-size:18px;">//StaticMethodParent.js
- export default class StaticMethodParent{
- static getCommon(){
- return '父类的静态方法';
- }
- }
- //通过子类直接调用
- console.log(StaticMethod.getCommon());
- 如果StaticMethod继承StaticMethodParent,StaticMethodParent的静态方法,可以在StaticMethod中用super调用。
- //定义静态方法
- static getAge(){
- //子类可以调用父类的静态方法
- console.log(super.getCommon());
- return '获取Age的静态方法';
- }</span>
3.Class静态属性和实例属性
静态属性指的是Class本身的属性,即Class.propname,而不是定义在实例对象(this)上的属性。ES6使用静态属性和实例属性:
- <span style="font-size:18px;">//StaticMethod.js
- //定义静态属性
- StaticMethod.firstName = 'pca';
- console.log(StaticMethod.firstName);
- //定义实例属性
- //ES6实例属性只能在constructor构造函数中定义
- constructor() {
- super();
- this.width = '40cm';
- }
- getWidth(){
- return this.width;//使用的时候需要加上this
- }
- //为了可读性的目的,对于那些在constructor里面已经定义的实例属性,新写法允许直接列出。
- width;</span>
ES7有一个静态属性的提案,目前Babel转码器支持。安装babel-preset-stage-0 包含了0-3的stage,可根据需要添加,不同的stage封装了不同的插件,官方推荐是使用stage-1
安装命令(根据自己的需求调整):
- <span style="font-size:18px;">npm install --save babel-preset-stage-0</span>
- <span style="font-size:18px;">//StaticMethod.js
- //ES7提案 定义静态属性
- static lastName = 'pcaca';
- //ES7定义实例属性
- height = '150cm';</span>
Class的静态方法/Class静态属性和实例属性的整个案例:
- <span style="font-size:18px;">//StaticMethodParent.js
- export default class StaticMethodParent{
- static getCommon(){
- return '父类的静态方法';
- }
- }
- //StaticMethod.js
- import StaticMethodParent from './StaticMethodParent'
- //定义静态属性和静态方法
- class StaticMethod extends StaticMethodParent{
- //因为ES6明确规定,Class内部只有静态方法,没有静态属性,所以ES6在类中定义静态属性都是错误的。
- //static lastName = 'pcaca';ES6错误
- //ES7提案 定义静态属性
- //安装babel-preset-stage-0 包含了0-3的stage,可根据需要添加,
- //不同的stage封装了不同的插件,官方推荐是使用stage-1
- static lastName = 'pcaca';
- //ES7定义实例属性
- height = '150cm';
- getHeight(){
- return this.height;//ES7的使用也要加上this
- }
- //ES6实例属性只能在constructor构造函数中定义
- constructor() {
- super();
- this.width = '40cm';
- }
- //为了可读性的目的,对于那些在constructor里面已经定义的实例属性,新写法允许直接列出。
- width;
- getWidth(){
- return this.width;//使用的时候需要加上this
- }
- //定义静态方法
- static getAge(){
- //子类可以调用父类的静态方法
- console.log(super.getCommon());
- return '获取Age的静态方法';
- }
- };
- //定义静态属性
- StaticMethod.firstName = 'pca';
- export {StaticMethod};
- //index.js
- import {StaticMethod} from './StaticMethod';
- console.log(StaticMethod.getAge());
- console.log(StaticMethod.getCommon());
- console.log(StaticMethod.firstName);
- console.log(StaticMethod.lastName);
- let staticMethod = new StaticMethod();
- console.log(staticMethod.height);
- console.log(staticMethod.getHeight());
- console.log(staticMethod.width);
- console.log(staticMethod.getWidth());
- //staticMethod.getAge();//bundle.js:7906 Uncaught TypeError: staticMethod.getAge is not a function</span>
ES6 类(Class)基本用法和静态属性+方法详解
博客地址:http://blog.csdn.net/pcaxb/article/details/53759637
下载地址:http://download.csdn.net/detail/pcaxb/9716137
阅读全文
0 0
- ES6中的class创建类
- es6中的class类
- es6中的class类下
- ES6:JavaScript中的类Class
- ES6中的类(Class)的写法
- es6中的class
- 小程序中的ES6 Class
- ES6 Class 中的 super 关键字
- es6 javascript中的class理解
- ES6 Class 类
- es6 class类
- es6 javascript的class类中的 get和set
- JavaScript 使用对象及ES6中的class
- ES6--Class
- ES6 Class
- ES6--class
- ES6-class
- 【ES6】class
- Zookeeper的初步认识
- Swoole2.0内置协程并发测试
- 选择器优先级
- productFlavors基本应用
- LeetCode----- 7.Reverse Integer
- ES6中的class创建类
- 基于MFC的五子棋应用(一)
- [effectiv c++]条款37:绝不重新定义继承而来的缺省参数值(动态绑定,静态绑定,多态性)
- JAVA的静态代理与动态代理比较
- unity Dictionary序列化和反序列化及XML本地数据存储
- hdu_1907_尼姆博弈_最后一个取完就输掉
- IO
- Linux系统负载升高排查思路
- vue项目优化之页面的按需加载(vue+webpack)