咏竹莉
where there is a will,there is a way

· class 是ES6 提供的更接近于传统语言的写法, 作为对象的模板,通过class 关键字,可以定义类

· class 写法只是一个语法糖,它只是让对象原型的写法更加清晰,更像面向编程的语法。例如

// 传统原型对象写法
  function Person(x,y) {
    this.x  = x;
    this.y = y;
  }
  // 原型上添加方法
  Person.prototype.add = function () {
    return  this.x + this.y
  }
  let person1 = new Person(2,3)
  console.log(person1.add());  5 

   // class 写法
   // 注意: 定义类的写法的时候,不需要加上function 关键字
   // 方法之间不需要用逗号间隔,否则会报错
   class Person2 {
     constructor(x,y) {
       this.x = x;
       this.y = y
     } 
     add() {
       return this.x + this.y
     }
   }
   let person2 = new Person2(2,3)
   console.log(person2.add());

 

· 类完全可以看作构造函数的另一种写法:  Person === Person.prototype.constructor

· 使用类的时候直接像对象一样new即可

class Bar {
   sing () {
      console.log('xiaozhu')
   }
}

const bar = new Bar()

bar.sing();  // xiaozhu

 

· 构造函数的prototype属在类上依然存在,实际上,类中所有的方法都定义在类的prototype属性上

class Person {
   constructor () { 
       // ...
    }
    sing () {
       // ... 
    }
    dance() {
      // ...
    }
}

// 等同于
Person.prototype = {
  constructor() {},
  sing() {},
  dance () {}

}

 

· 类的实例上调用方法实际上就是调用原型上的方法

class A {}
var a = new A();
a.constructor === A.prototype.constructor

 

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

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

 

· 类和模块的内部默认都是严格模式,所以不需要 use strict 指定运行模式

· constructor 方法

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

   2. 一个类必须有constructor方法,如果没有显式定义,会默认添加一个空constructor方法

   3. constructor 默认返回实例对象(this), 完全可以指定返回另一个对象

    

  

// 改变返回的对象为空对象,因此通过new Foo() 创建的实例不能继承自Foo
class Foo {
      constructor () {
        return Object.create(null);
      }
 }

 console.log(new Foo() instanceof Foo);  // false 

 

  4. 类必须使用new 调用,否则会报错。 普通构造函数不用new 也可以执行, 类不行

 

 

Object.create()

Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__ 

demo: 

// Object.create()方法 ,使用现有的对象来提供新创建对象的__proto__
    const person = {
      isMe: false,
      name: 'xiaoping',
      sing: function(){
        console.log(`My name is ${this.name}, Am i xiaozhu ${this.isMe}`)
      }
    }
    const me = Object.create(person);
    me.name = 'xiaozhu'
    me.isMe = true
    me.sing();  // My name is xiaozhu, Am i xiaozhu true

 

类的实例对象

  1.  前面提到过, 生成类的实例对象的写法与ES5 完全一致,使用 new 命令即可,但是如果没有加new 这会报错

  2.  与ES5 一样,  实例的属性除非显式定义在this 对象上,否则都是定义在原型上(也就是class 上的prototype上)

  

class fruit {
      constructor (name,breed) {
        this.name = name;
        this.breed = breed
      }

      info() {
        console.log(`此${this.name} 是 ${this.breed}`)
      }    
    }

    const fruit1 = new fruit('苹果','应季水果')
    fruit1.info(); // 此苹果是 应季水果
    console.log(fruit1.hasOwnProperty('name'));   // true
    console.log(fruit1.hasOwnProperty('breed')); // true
    console.log(fruit1.hasOwnProperty('info'));   //  false
    console.log(fruit1.__proto__.hasOwnProperty('info'));  // true
    console.log(fruit.prototype.constructor);   // 指向fruit 

 

  3. 类的所有实例共享一个原型对象

var p1 = new Point(1,2);
var p2 = new Point(1,2);
p1.__proto__ === p2.__proto__  ;  // true
// p1.__proto__ === Point.prototype
    

 

类的特性

· 不存在变量提升:  类不存在变量提升,必须先声明后使用

· 私有方法ES6不提供,只能模拟实现

· 私有属性: ES6不支持私有属性, 有个方案,就是在属性名之前使用# 表示

 

this 的指向

· 类的方法内部如果有this, 它默认指向类的实例

 

class的静态方法

1. 类相当于实例的原型,所有在类中定义的方法,都会被实例继承,如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就是静态方法

     class Fol {
        static classMethod() {
          console.log( 'hello xiaozhu')
        }
      }
      Fol.classMethod(); // hello xiaozhu
      let fol = new Fol()
      fol.classMethod();  //  Uncaught TypeError: fol.classMethod is not a function

 

向类中添加方法

通过Object.assign, 在原型上追加方法

      class Person11 {
         constructor (name) {
           this.name = name
         }
         sing() {
            console.log(`${this.name} 唱歌`)
         }
       }

       Object.assign(Person11.prototype,{
         dance() {
           console.log(`${this.name} 在唱歌 `)
         },
         // 注意 不能再添加构造方法 undefined
        //  constructor(age) {
        //   this.age = age
        //  }
       })

       let per11 = new Person11('xiaozhu');  // xiaozhu 在唱歌
       per11.dance()

 

 

类和构造函数的区别

1. 类必须使用new 调用,否则会报错,这是它跟普通构造函数的一个主要区别,后者不用new 也可以执行

2. 类的所有实例共享一个原型对象

3. 类的内部默认是严格模式,所以不需要使用use strict 指定运行模式

posted on 2021-04-25 17:50  咏竹莉  阅读(380)  评论(0)    收藏  举报