· 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 指定运行模式
浙公网安备 33010602011771号