相同点
1. 都可作为构造函数
函数作为构造函数
如下代码,函数作为构造函数的写法。函数中的this是指向构造函数创建的实例p。
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);
console.log(p) // Point {x: 1, y: 2}
class作为构造函数
类包含构造函数、实例方法、取值函数getter、存值函数setter、静态方法、静态属性、私有方法、私有属性但这些都不是必须的。
下面方法定义了一个“类”,可以看到里面有一个constructor()方法,这就是构造方法,而this关键字则代表实例对象。
定义toString()方法,就是实例方法,类的所有实例方法都定义在类的prototype属性上面。 前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法与方法之间不需要逗号分隔,加了会报错。
使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var p = new Point(1, 2);
console.log(p) // Point {x: 1, y: 2}
不同点
1. class构造函数必须用new操作符
class构造函数与function构造函数的主要区别为,调用class构造函数必须使用new操作符。而普通function构造函数如果不使用new调用,那么会以全局的this(在浏览器中是window)作为内部对象。
如下代码,普通function函数把window作为this
function point(){}
var p = Point();
调用class构造函数如果忘记使用new命令,将会报错。
class Point {
// ...
}
// 报错
var point = Point(2, 3); // Uncaught SyntaxError: Identifier 'Point' has already been declared
// 正确
var point = new Point(2, 3);
2. class声明不可以提升
function构造函数声明存在提升,如下代码是不会报错的。
const usr = new Foo('Jack');
console.log(usr); // Foo { name: 'Jack' }
function Foo(name) {
this.name = name;
}
类不存在变量提升(hoist)。
const usr = new Foo('Jack'); // ReferenceError: Foo is not defined
console.log(usr);
class Foo {
constructor(name){
this.name = name;
}
}
3. class不可以用call、apply、bind改变执行上下文改变其this指向。
普通function构造函数是可以通过 call apply bind。如下代码sayName调用call改变其this到obj对象上,输出的name就是obj中的name。
function sayName() {
console.log(this.name);
}
const obj = { name: 'Jack', };
sayName.call(obj); // Jack
若class使用call 、apply、 bind改变this指向则会报错。
class sayName {
constructor(){
console.log(this.name);
}
}
const obj = { name: 'Jack', };
sayName.call(obj); // Jack
4. 类的内部所有定义的方法,都是不可枚举的,函数定义的方法是可以枚举的。
function构造函数的方法是可以枚举的,如下使用Object.keys获取prototype上的方法名,会打印出prototype上的方法
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
console.log(Object.keys(Point.prototype)) // ['toString']
class类内部定义的方法都是不可以枚举的,如下代码Object.keys(Point.prototype)打印出的是空数据
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
console.log(Object.keys(Point.prototype)) // []
参考: