Class

作者: zdxhxh | 来源:发表于2019-11-28 09:34 被阅读0次

面向对象oop是业务编程的核心,精通oop等于精通世界万物,无所不能

在JS中,生成实例的传统方法的通过构造函数

而继承往往通过prototype这个对象实现

class

es6的class只是一个语法糖,它的继承模式由es5就可以做到

新的class写法只是让对象原型的写法更加清晰

class A { 
  constructor(x,y) { 
    this.x = x 
    this.y = y
  }
  toString() { 
    ...
  }
}

定义类方法的时候,前面不需要加上function这一个关键字,直接把函数定义放进去就行了

与传统es5的方法一样,类方法函数在prototype上

但要明白的是,class不支持安全模式,必须使用关键字new 创建对象

class A {}
const a = A() // logs TypeError: Class constructor A cannot be invoked without 'new'

与es5不同的时,类的方法(包括构造函数)是不可枚举的,这意味着它不会在for in中出现

class A { 
  toString() { 
    console.log('我想搞事情')
  }
}
console.log(Object.keys(A.prototype)) // logs []
console.log(Object.getOwnPropertyNames(A.prototype)) // logs [ 'constructor', 'toString' ]

B.prototype.toString = function() { 
  console.log('BBBBB')
}
console.log(Object.keys(B.prototype)) // logs [ 'toString' ]
console.log(Object.getOwnPropertyNames(B.prototype)) // logs [ 'constructor', 'toString' ]

constutor

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

class A {} 
// 等于
class A {
  construtor() {}
} 

constructor方法默认返回实例对象(即this),当然,你也可以指定返回另外一个对象。

实例

注意 : 在浏览器环境中,浏览器厂商实现了proto的私有属性,该属性会指向实例的原型对象,但不建议在生产环境使用该属性,我们可以使用Object.getPrototypeOf方法获取实例对象的原型

取值函数(getter)和存值函数(setter)

在类的内部可以使用get和set关键字,对某个属性设置存值函数与取值函数 拦截该属性的存储行为

class A { 
  constructor() { }
  get prop() {
    return 'getter'
  }
  set prop(value) {
    console.log('setter' + value)
  }
}

存值函数与取值函数是设置在属性的Descriptor对象上的

var descriptor = Object.getOwnPropertyDescriptor(
  A.prototype, "prop"
);

"get" in descriptor  // true
"set" in descriptor  // true

属性表达式

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

class A { 
  constructor(length)
  ["fuckyou"]() { 

  }
}

上面的代码中,,Squrae类的方法名为getArea

class表达式

与函数一样,类也可以使用表达式的形式定义。

const MyClass = class Me {
  getClassName() {
    return Me.name;
  }
};

根据这一特性,可以写出立即执行的Class

let a = new class {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log(this.name);
  }
}('张三');

a.sayName(); // "张三"

注意点

  • class默认严格模式
  • 暂时性死区,es5构造函数会存在提升现象,而es6不存在提升,这意味着在class定义前会出现暂时性死区
  • name,函数具有name属性,es6的class也一样
  • 静态方法,class内部用static声明的方法不会被继承,只能通过类名调用,这与java一样
  • class中,实例属性可以直接书写xxx = '',而不写在构造函数中,一般用于给实例赋予初始属性而使用

new.target

es6为new命令新增了一个target属性,返回new命令作用域的那个构造函数,如果构造函数没有使用new命令,则该属性为undefined,这优点类似安全模式

我们可以使用这个命令代替安全模式的前置判断

function A(xx) { 
  if(this instanceof A) {
    this.xx = xx 
  } else { 
    return new A(xx)
  }
}

function A(xx) { 
  if(new.target === A) { 
    this.xx = xx
  } else { 
    return new A(xx)
  }
}

当然,它的正确使用应该是写抽象类的时候

class A{ 
  constructor() { 
    if(new.target ===  A) { 
      // 抛出错误 : 本类不能实例化
      return new TypeError('this is abstract class you must inhert and complete it') 
    }
  }
}

相关文章

网友评论

      本文标题:Class

      本文链接:https://www.haomeiwen.com/subject/vduvwctx.html