ES5 生成实例对象的传统方法是通过构造函数。如下代码。这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大。
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
ES6 引入了 Class(类)这个概念。它的绝大部分功能,ES5 都可以做到,上面的代码用 ES6 的class
改写。
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
typeof Point // 数据类型是function
Point === Point.prototype.constructor // true 类本身就指向构造函数
var b = new Point ();
b.toString() // 这是类的使用方法 用new
这是定义了一个“类”,里面有一个constructor
方法,这就是构造方法,而this
关键字则代表实例对象。也就是说,ES5 的构造函数Point
,对应 ES6 的Point
类的构造方法,也就是constructor
方法。
Point
类除了构造方法,还定义了一个toString
方法。注意,前面不需要加上function
这个关键字,方法之间不需要逗号分隔,加了会报错。
构造函数的prototype
属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype
属性上面。如下
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
// 这个 类 等同于 Point.prototype = { //ES5 的 构造函数,在prototype 上添加方法
constructor() {},
toString() {},
toValue() {},
};
let b = new Point(); //new方法生产实例对象
b.constructor === Point.prototype.constructor //实例对象的constructor =Point这个类的原型的
constructor
由于类的方法都定义在prototype
对象上面,所以类的新方法可以添加在prototype
对象上面。Object.assign
方法可以很方便地一次向类添加多个方法。
assign是什么???
//Object.assign()接口可以接收多个参数,第一个参数是目标对象
var target = {a : 1}; //目标对象
var source1 = {b : 2}; //源对象1
var source2 = {c : 3}; //源对象2
var source3 = {c : 4}; //源对象3,和source2中的对象有同名属性c
Object.assign(target,source1,source2,source3);
//结果如下:
//{a:1,b:2,c:4}
//Object.assign进行的拷贝是浅拷贝。也就是说,如果拷贝过来的属性的值是对象等复合属性,那么只能拷贝过来一个引用
继续我们的话题,下面是代码例子。在Point类 添加了两个方法。
class Point {
constructor(){
// ...
}
}
Object.assign(Point.prototype, {
toString(){},
toValue(){}
});
类的内部所有定义的方法,都是不可枚举的,这一点与 ES5 的行为不一致。
class Point {
constructor(x, y) {
// ...
}
toString() {
// ...
}
}
Object.keys(Point.prototype)
// [] 返回空数组 说明没有可枚举的属性。
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"] //获取对象全部属性
//这是ES5的写法 它就可以枚举
var Point = function (x, y) {
// ...
};
Point.prototype.toString = function() {
// ...
};
Object.keys(Point.prototype)
// ["toString"] 返回可枚举的属性
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]
Object.keys和Object.getOwnPropertyNames的方法谅解:https://www.cnblogs.com/37sky/articles/5324105.html
类和模块的内部,默认就是严格模式,所以不需要使用use strict
指定运行模式。
二,constructor
方法
constructor
方法是类的默认方法。一个类必须有constructor
方法,如果没有,默认添加一个空的constructor
。
constructor
方法默认返回实例对象(即this
),也可以指定返回另外一个对象。
类必须使用new
调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new
也可以执行。