• ES6原生Class


    es5 之前定义构造函数的方法

    // 先定义一个函数,强行叫它构造函数,大写的P也不是必须的,只是约定俗成
    function Point(x, y) {
      this.x = x; // 构造函数的属性都定义在函数内部
      this.y = y; // this指向实例对象
    }
    
    // 构造函数的方法都定义在构造函数的原型上
    Point.prototype.toString = function () {
      return '(' + this.x + ', ' + this.y + ')';
    };
    
    // new 一个对象,就OK了
    var p = new Point(1, 2);

    es6 定义类常见方法

    //定义类
    class Point {
      constructor(x, y) { // 定义构造方法
        this.x = x; // this指向实例对象
        this.y = y;
      }
      toString() { // 定义一个方法,注意这里没有function关键字
        return '(' + this.x + ', ' + this.y + ')'; // this指向实例对象
      }
    }
    var test = new Point(2,3);//实例化
    console.log(test.toString());//(2, 3)

       基本上,ES6的class可以看做知识一个语法糖,它的绝大部分功能,ES5都可以看到,新的class写法只是让对象原型的写法更加清晰,更像面向对象编程语法而已

       定义了一个Point类,他里面有个constructor方法,这就是构造方法;而this关键字则代表实例对象,也就是说,ES5的构造函数Point,对应ES6的Point类的构造方法; 

     Point类除了构造方法,还定义了一个toString方法,定义类的方法的时候,前面不需要加function这个关键字,直接将函数定义放进去就行了 ,另外,方法之间不需要逗号分隔;

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

    constructor方法
    constructor方法是类的默认方法,通过new生产对象实例时,自动调用该方法,一个类必须有constructor方法,如果没有定义,则默认添加空的constructor方法
    class Point{
    }
    //等同于
    class Point {
         constructor () { }
    }
    constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象
    class Person {
         constructor  () {
             return {};
         }
    }

    类就是function 的另一种写法,本身还是function

    class Point {
            }
    console.log(typeof Point);// "function" 类的数据类型就是函数
    console.log(Point === Point.prototype.constructor);// true 类本身就指向构造函数

    this指向

    class Logger {
        printName(name = 'there') {
            this.print(`Hello ${name}`);
        }
        print(text) {
            console.log(text);
        }
    }
    const logger = new Logger();
    const printName = logger.printName;
    logger.printName(); 这样不会报错
    printName();//报错
    printName方法中的this,默认指向Logger类的实例。但是,如果将这个方法提取出来单独使用,this会指向该方法运行时所在的环境,因为找不到print方法而导致报错。

     get与set

      getter可以用来得获取属性,setter可以去设置属性

      

    class Person {
        constructor(){
            this.hobbies = [];
        }
        set hobby(hobby){
            this.hobbies.push(hobby);
        }
        get hobby(){
            return this.hobbies;
        }
    }
    let person = new Person();
    person.hobby = 'basketball';
    person.hobby = 'football';
    console.log(person.hobby);//["basketball", "football"]

    class 的静态方法

    类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
    class Point{
         static classMethod(){
             return 'hello';
         }
    }
    Point.classMethod();//hello
    如果在实例上调用静态方法,会抛出一个错误,表示不存在该方法。注意,如果静态方法包含this关键字,这个this指的是类,而不是实例。
    class Point{
        static classMethod(){
            return this.getName();
        }
        static getName(){
            return 'zs';
        }
        getName(){
            return 'ls';
        }
    }
    console.log(Point.classMethod());//zs

    class 的静态属性和实例属性

    静态属性指的是 Class 本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。
    class Foo {
    }
    Foo.prop = 1;
    Foo.prop // 1
    //Foo类定义了一个静态属性prop,只有这种写法可行,因为 ES6 明确规定,Class 内部只有静态方法,没有静态属性。
    类的实例属性-->类的实例属性可以用等式,写入类的定义之中
    class Point{
        num = 30;
        constructor(){
            console.log(this.num);//30
        }
    }
    //num就是Point的实例属性。在Point的实例上,可以读取这个属性。
    var test = new Point();
    console.log(test.num);//30
    
    

    class的继承

    父类的静态方法,可以被子类继承。
    class parent{
        static getName(){
            return 'parent';
        }
    }
    class child extends parent{
    }
    console.log(child.getName());//parent
    
    

    (1)子类没constructor时

    子类American继承父类Person,子类没用定义constrcutor,则默认添加一个,并且在constrcutor中调用super函数,相当于调用父类的构造函数。调用super函数是为了在子类中获得父类的this,调用之后this指向子类。

    class parent{
        foo(){
            return 'foo';
        }
    }
    class child extends parent{
        get(){
            return this.foo()
        }
    }
    var test = new child();
    console.log(test.foo());//foo
    console.log(test.get());//foo

    (2)子类有constructor

    子类必须在constructor方法中调用super方法,否则new实例时会报错。因为子类没有自己的this对象,而是继承父类的this对象, 相当于 parent.prototype.constructor.call(this)
    如果不调用super函数,子类就得不到this对象。super()作为父类的构造函数,只能出现在子类的constructor()中,但是super指向父类的原型对象,可以调用父类的属性和方法。
    class parent{
        foo(){
            return 'foo';
        }
    }
    class child extends parent{
        constructor(){
            super()
        }
        get(){
            return this.foo()
        }
    }
    var test = new child();
    console.log(test.foo());//foo
    console.log(test.get());//foo
    
    



  • 相关阅读:
    day2 python基础
    day2 jmeter和charles
    nmon参数详解
    根据路径遍历该路径下的文件夹和文件并以列表形式显示出来、文件(夹)的复制
    GridView创建菜单栏
    GridView(网格视图)+MotionEvent(触控事件)实现可以拖动排序的网格图
    android 下拉刷新框架PullToRefreshScrollView(com.handmark.pulltorefresh)
    android轮播图的实现原理
    自定义进度条渐变色View
    android显示通知栏Notification以及自定义Notification的View
  • 原文地址:https://www.cnblogs.com/bruce-gou/p/10405800.html
Copyright © 2020-2023  润新知