一、ECMAScript 5标准中的类
1、定义原型类
/* 定义Calcula类 */
var Calcula = function (x, y) {
this.x = x;
this.y = y;
}
/* 此处使用了Object.defineProperties方法给Calcula.prototype添加方法,是
* 为了保证类与ES6-Class编译后的类保持相同的特性,非必需不使用也可以
*/
Object.defineProperties(Calcula.prototype, {
add: {
configurable: false,
enumerable: false,
value: function () {
return this.x + this.y;
},
writable: false
},
sub: {
configurable: false,
enumerable: false,
value: function () {
let x = this.x;
let y = this.y;
if (x > y) {
return x - y;
} else if (x < y) {
return y - x;
} else {
return 0;
}
},
writable: false
}
});
const calcula = new Calcula(100, 900);
console.log(calcula.sub());
2、原型类继承
下面是一典型的关于原型继承的代码。
/* 创建Foo原型类的Constructor函数 */
var Foo = function (name) {
this.name = name;
}
/* 为Foo原型类添加prototype方法*/
Foo.prototype = {
myName: function () {
console.log(this.name);
return this.name;
};
};
/* 创建Bar原型类的Constructor函数,并将this指针绑定到Foo类,使得Bar类的实例可以访问Foo类的属性和方法*/
var Bar = function (name, label) {
Foo.call(this, name);
this.label = label;
}
/* 创建Bar类并使用Foo.prototype对象作为新创建的Bar类的prototype对象 */
Bar.prototype = Object.create(Foo.prototype);
/* 为Bar类添加方法*/
Bar.prototype = {
myLabel: function () {
console.log(this.label);
return this.label;
};
};
const a = new Bar("编程语言JavaScript", "它是一门弱类型语言");
a.myName();
a.myLabel();
3、静态类
调用该类的静态方法不需要类的实例,该类的实例无法调用该类的任一静态方法,这也意味着类的静态方法内部的this指针是指向类本身的,而不是指向其实例
。静态方法通常用于为一个应用程序创建工具函数。
var Point = function (x, y) {
this.x = x;
this.y = y;
};
Point.distance = function (a, b) {
const x = a - b;
const y = a + b;
return Math.hypot(x, y);
};
console.log(p1.distance(10, 10)); // 因实例无法调用静态方法,所以浏览器会报错
console.log(Point.distance(p1, p2));
4、原型类扩展-继承常规对象
如果原型类要继承一个常规对象,则可以将对象设置为原型类的protoype对象。
/* 实例1:类继承常规对象(JSON)*/
var Animal = {
hobby: ["篮球", "编程"],
speak() {
console.log(this.name + ' can speak English!');
console.log(this.hobby);
}
};
var Person = function (name) {
this.name = name;
};
Person.prototype = Animal;
var p = new Person("小明");
p.speak();
二、ECMAScript 6标准中的类
1、类
/* 定义Greeter类,并添加Constructor构造器和greet方法 */
class Greeter {
constructor(message) {
this.greeting = message;
}
greet() {
return "你好," + this.greeting;
}
}
let greeter = new Greeter("world");
console.log(greeter.greet());
声明了一个Greeter的类,它有3个成员:类的属性(greeting)、类的构造器(Constructor)、类的方法(greet)。
当我们使用new
关键字实例化Class的时候,首先会执行自己的构造器中的方法。
2、类继承
extends
关键字在类声明或类表达式中用于创建一个继承于另一个类的子类。
class Animal {
constructor(name) {
this.name = name;
}
eat() {
console.log(this.name + '会汪汪叫');
}
}
class Dog extends Animal {
constructor() {
super();
}
}
var d = new Dog('狗A');
d.eat();
如果子类中存在构造函数,则需要在使用“this”之前首先调用super()。
3、静态类
static
关键字用来定义一个类的一个静态方法,调用该类的静态方法不需要类的实例,该类的实例无法调用该类的任一静态方法,这也意味着类的静态方法内部的this指针是指向类本身的,而不是指向其实例
。静态方法通常用于为一个应用程序创建工具函数。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
console.log(p1.distance(10, 10)); // 因实例无法调用静态方法,所以浏览器会报错
console.log(Point.distance(p1, p2));
4、类扩展-类继承常规对象
请注意,类不能扩展常规(不可构造/非构造的)对象。如果要继承常规对象,可以改用Object.setPrototypeOf()
:
/* 实例1:类继承常规对象(JSON)*/
const Animal = {
hobby: ["篮球", "编程"],
speak() {
console.log(this.name + ' can speak English!');
console.log(this.hobby);
}
};
class Person {
constructor(name) {
this.name = name;
}
}
// 以Animal对象作为Person类的原型对象
Object.setPrototypeOf(Person.prototype, Animal);
const d = new Person("小明");
d.speak();
/* 实例2:类继承常规对象(Array)*/
const methods = [
"正弦",
"余弦",
{
name: "小明",
hobby: [
"编程", "LOL"
]
}
];
class Methods {
constructor(name) {
this.name = name;
}
}
Object.setPrototypeOf(Methods.prototype, methods);
const methodsItem = new Methods("小明");
console.log(methodsItem[2]);