• Class 学习 (Es6阮一峰)


     

    es5 构造函数 实例:

     1 function Point(x, y) {
     2   this.x = x;
     3   this.y = y;
     4 }
     5 
     6 Point.prototype.toString = function () {
     7   return '(' + this.x + ', ' + this.y + ')';
     8 };
     9 
    10 var p = new Point(1, 2);

    作为对象的模板,通过class关键字,可以定义类,相当于创建一个 实例

     1 //定义类
     2 class Point {
     3   constructor(x, y) {
     4     this.x = x;
     5     this.y = y;
     6   }
     7 
     8   toString() {
     9     return '(' + this.x + ', ' + this.y + ')';
    10   }
    11 }
    12 typeof Point // "function"
    13 Point === Point.prototype.constructor // true
    14 //ES6 的类,完全可以看作构造函数的另一种写法。

    可以看到里面有一个constructor方法,这就是构造方法,this则代表实例对象

    ES5 的构造函数Point,对应 ES6 的Point类的构造方法。

    定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

    类的数据类型就是函数,类本身就指向构造函数。 直接对类使用new命令,跟构造函数的用法完全一致。

    构造函数的prototype属性,在 ES6的“类”上面继续存在。 事实上,类的所有方法都定义在类的prototype属性上面。

    class Point {
      constructor() {
        // ...
      }
    
      toString() {
        // ...
      }
    
      toValue() {
        // ...
      }
    }
    
    // 等同于
    
    Point.prototype = {
      constructor() {},
      toString() {},
      toValue() {},
    };

    Object.assign方法可以很方便地一次向类添加多个方法:

     1 Object.assign(Point.prototype, {
     2   toString(){},
     3   toValue(){}
     4 });
    5// 类的内部所有定义的方法,都是不可枚举的 6 7 Object.keys(Point.prototype) 8 // [] es5 : ["toString"] 9 Object.getOwnPropertyNames(Point.prototype) 10 // ["constructor","toString"]

    类的属性名,可以采用表达式。

    let methodName = 'getArea';
    
    class Square {
      constructor(length) {
        // ...
      }
    
      [methodName]() {
        // ...
      }
    }

    类和模块的内部,默认就是严格模式 只要你的代码写在类或模块之中,就只有严格模式可用。 ES6 实际上把整个语言升级到了严格模式

     

    constructor方法

    constructor方法是类的默认方法, 通过new命令生成对象实例时,自动调用该方法

    一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。 相当于es5 new Vue

     1 class Point {
     2 }
     3 
     4 // 等同于 
     5 class Point {
     6   constructor() {} //JavaScript 引擎会自动为它添加一个空的constructor方法。
     7 }
     8 // 等同于
     9 new Point (){
    10     
    11 }
    12 constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
    13 
    14 class Foo {
    15   constructor() {
    16     return Object.create(null);
    17   }
    18 }
    19 
    20 new Foo() instanceof Foo
    21 // false

    类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行, 与 ES5 一样,类的所有实例共享一个原型对象。

     私有属性

    表达式定义一个类

     1 const MyClass = class Me {
     2   getClassName() {
     3     return Me.name;
     4     //这个类的名字是MyClass而不是Me,Me只在 Class 的内部代码可用,指代当前类。
     5   }
     6 };
     7 //内部没用到Me的话可以省略Me
     8 const YouClass = class {
     9 //...
    10 };
    11 采用 Class 表达式,可以写出立即执行的 Class。
    12 
    13 let person = new class {
    14   constructor(name) {
    15     this.name = name;
    16   }
    17 
    18   sayName() {
    19     console.log(this.name);
    20   }
    21 }('张三');
    22 
    23 person.sayName(); // "张三"

    不存在变量提升(hoist),必须保证子类在父类之后定义),这一点与 ES5 完全不同。

    new Foo(); // ReferenceError
    class Foo {}
    

    继承类

    {
      let Foo = class {};
      class Bar extends Foo {
      //Bar继承Foo
      }
    }
    

    私有方法

    私有方法是常见需求,但 ES6 不提供,只能通过变通方法模拟实现

    有三种方法可模拟

    //第一种
    class Widget {
    
      // 公有方法
      foo (baz) {
        this._bar(baz);
      }
    
      // 私有方法
      _bar(baz) {
        return this.snaf = baz;
      }
    
      // _bar方法前面的下划线,表示这是一个只限于内部使用的私有方法 但是,在类的外部,还是可以调用到这个方法。
    }
    
    
    
    //第二种
    class Widget {
      foo (baz) {
        bar.call(this, baz);
      }
    
      // 内部调用了bar.call(this, baz),成为了当前模块的私有方法
    }
    //私有方法移出模块
    function bar(baz) {
      return this.snaf = baz;
    }
    
    
    //第三种
    const bar = Symbol('bar');
    const snaf = Symbol('snaf');
    
    export default class myClass{
    
      // 公有方法
      foo(baz) {
        this[bar](baz);
      }
    
      // 私有方法 
      [bar](baz) {
        return this[snaf] = baz;
      }
    
      // 利用Symbol值的唯一性,将私有方法的名字命名为一个Symbol值。
    };

    私有属性的提案

    方法是在属性名之前,使用#表示。

    class Point {
      #x=0;// 私有属性可以指定初始值,在构造函数执行时进行初始化。
    
      constructor(x = 0) {
        #x = +x; // 写成 this.#x 亦可
      }
    
      get #x() { return #x }
      set #x(value) { #x = +value }
      #sum() { return #a + #b; }  //私有方法
      
      //  #x是一个私有属性,它的读写都通过get #x()和set #x()来完成。 #x和x是两个不同的属性
    }
    //JavaScript 是一门动态语言,没有类型声明,使用独立的符号似乎是唯一的比较方便可靠的方法,能够准确地区分一种属性是否为私有属性。"@" 已经留给了 Decorator。

    私有属性不限于从this引用,类的实例也可以引用私有属性

    class Foo {
      #privateValue = 42;
      static getPrivateValue(foo) {
        return foo.#privateValue;
      }
    }
    
    Foo.getPrivateValue(new Foo()); // 42
    console.log(Foo.#privateValue) // 报错


    //class 的取值函数(getter)和存值函数(setter) class MyClass { constructor() { // ... } get prop() { return 'getter'; } set prop(value) { console.log('setter: '+value); } } let inst = new MyClass(); inst.prop = 123; // setter: 123 inst.prop // 'getter'
     

     

  • 相关阅读:
    Java实现第九届蓝桥杯第几天
    Java实现第九届蓝桥杯第几天
    Java实现第九届蓝桥杯第几天
    Java实现第九届蓝桥杯第几天
    Java实现第十届蓝桥杯特别数的和
    Mysql大数据备份和增量备份及还原
    学会4种备份MySQL数据库(基本备份方面没问题了)
    解决表单提交参数乱码问题【终极版】不看后悔
    聊聊单元测试(三)——Spring Test+JUnit完美组合
    eclipse gradle插件(buildship)的安装和使用
  • 原文地址:https://www.cnblogs.com/gaoguowen/p/10073034.html
Copyright © 2020-2023  润新知