在ES5声明一个函数(能够new),再将方法添加到这个方法的原型上,来建立自定义类型。javascript
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
let person = new Person("xunuo0x");
person.sayName(); // 输出 "xunuo0x"
console.log(person instanceof Person); // true
console.log(person instanceof Object); // true
复制代码
本质:ES5实现方式的语法糖java
咱们拿下面用class
声明的Person
为例:也就是说Person
类为一个具备构造函数行为的函数,其中内部方法sayName
实际上就是Person.prototype.sayName()
。因此说本质上是ES5实现方式的语法糖。函数
console.log(typeof Person) // 'function'
复制代码
区别在于,类的属性不可从新赋值和不可枚举的,Person.prototype
就是一个只读属性。性能
声明:ui
class Person {
// 等价于 Person 构造器
constructor(name) {
this.name = name;
}
// 更加简单的声明类的内部函数
// 等价于 Person.prototype.sayName
sayName() {
console.log(this.name);
}
}
let person = new Person("xunuo0x");
person.sayName(); // 输出 "xunuo0x"
console.log(person instanceof Person); // true
console.log(person instanceof Object); // true
console.log(typeof Person); // "function"
console.log(typeof Person.prototype.sayName); // "function"
复制代码
用ES5重写以下: 在实现的时候,主要使用Object.defineProperty()
实现class内部函数this
// 直接等价于 Person
let Person2 = (function() {
"use strict";
// 有个同名的只读内部函数
// **类的内部不能修改类名**
const Person2 = function(name) {
// 确认函数被调用时使用了 new
if (typeof new.target === "undefined") {
throw new Error("Constructor must be called with new.");
}
this.name = name;
}
Object.defineProperty(Person2.prototype, "sayName", {
value: function() {
// 确认函数被调用时没有使用 new
if (typeof new.target !== "undefined") {
throw new Error("Method cannot be called with new.");
}
console.log(this.name);
},
// **类的内部方法定义为不可枚举**
enumerable: false,
writable: true,
configurable: true
});
return Person2;
}());
复制代码
let Person = class{...}
let Person = PersonClass class{...}
const PersonClass
做为内部实现的类名js中能看成值来使用的称为一级公民spa
用法:prototype
// 类名做为参数传入函数
function crateObj (ClassName){
return new ClassName()
}
// 当即执行,实现单例模式
let person = new class {
constructor (name) {
this.name = name
}
say () {
console.log(this.name)
}
}('xunuo0x')
person.say() // "xunuo0x"
复制代码
Object.defineProperty()
定义Person.create() = function() {}
只要一个表达式能返回具备
[[constructor]]
就可使用extends
继承;也就是说能够继承一个函数code
ES5中的继承对象
function Parent (name) {
this.name = name
}
Parent.prototype.sayName = function () {
console.log(this.name)
}
function Child (name) {
Parent.call(this, name)
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
复制代码
在ES6中的继承
class Parent (name) {
constructor (name) {
this.name = name
}
sayName() {
console.log(this.name)
}
}
class Child extends Parent (name) {
constructor(name) {
super(name)
}
// 重写父类中的方法
sayName () {
console.log(`Child ${this.name}`)
}
}
复制代码
Symbol.species
属性Symbol.species
class MyClass extends Array {
static get [Symbol.species]() {
return this; // 默认返回MyClass类型
return Array; // 修改返回基类
}
constructor(value) {
this.value = value;
}
}
复制代码
constructor()
中new.target
不多是undefinedfunction mixin (...mixin) {
var base = function() {}
Object.assign(base, ...mixin)
return mixin
}
class Person extends mixin(Animal, Monkey) {
constructor(){
super(Animal, Monkey)
// ......
}
}
复制代码
class
简化了ES5中的继承,可是未改变现有的继承模型。能够理解为是ES5基于原型链的语法糖class
声明一个类,constructor()
做为构造函数,属性在constructor()
中初始化class
内能够定义getter/setter
访问器属性class
内定义非静态方法,静态方法绑定在构造器上class
必需要new
关键字extends
实现继承,子类中调用super()
访问父类构造函数extends
可能还会下降性能