这些可互换的语法是否可以创建JS类?我已经习惯了 class语法,但不完全了解它们之间的区别。
function User(name) {
this.name = name;
}
User.prototype.sayHi = function() {
alert(this.name);
}
let user = new User("John");
user.sayHi();
Run Code Online (Sandbox Code Playgroud)
与
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
let user = new User("John");
user.sayHi();
Run Code Online (Sandbox Code Playgroud)
类和构造函数之间的主要区别是:
没有类就不能调用类new,但是可以用作构造函数的函数可以(它们this将是错误的)
'use strict';
function Foo() {
console.log(this);
}
class Bar {
constructor() {
console.log(this);
}
}
Foo();
Bar();Run Code Online (Sandbox Code Playgroud)
与构造函数相比,类可以扩展更多类型(例如函数和数组)
'use strict';
function Foo(body) {
Function.call(this, body);
}
Object.setPrototypeOf(Foo, Function);
Foo.prototype = Object.create(Function.prototype);
class Bar extends Function {}
(new Bar('console.log(1)'))();
(new Foo('console.log(1)'))();Run Code Online (Sandbox Code Playgroud)
类的原型是它们的父级(它们继承静态属性)。构造函数的编写者通常不会为此而烦恼
非类不能扩展类(因为它们不能调用父构造函数–请参见第一点)
'use strict';
class Bar extends Function {}
function Foo() {
Bar.call(this);
}
Object.setPrototypeOf(Foo, Bar);
Foo.prototype = Object.create(Bar.prototype);
void new Foo();Run Code Online (Sandbox Code Playgroud)
类的作用域也类似于let/ const(块作用域,时间死区,不可重声明),而不是像var(函数作用域,提升的)或类似函数声明(它很复杂)。
在您的示例中,另一个区别是sayHi通过分配给新属性而不是使用eg来定义的Object.defineProperty,因此该属性的属性与类示例中的属性不同sayHi,在前者中是可枚举的,而在后者中则没有。
function UserA(name) {
this.name = name;
}
UserA.prototype.sayHi = function () {
alert(this.name);
};
class UserB {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
let a = [];
let b = [];
for (let key in new UserA()) a.push(key);
for (let key in new UserB()) b.push(key);
console.log(a, b);Run Code Online (Sandbox Code Playgroud)
来自MDN:
ECMAScript 2015 中引入的 JavaScript 类主要是 JavaScript 现有的基于原型的继承的语法糖。类语法并未向 JavaScript 引入新的面向对象的继承模型。
您可以使用Babel REPL之类的工具来查看上面的 ES6 基于类的代码如何转换为 ES5 基于原型的代码:
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
let user = new User("John");
user.sayHi();
Run Code Online (Sandbox Code Playgroud)
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var User = function () {
function User(name) {
_classCallCheck(this, User);
this.name = name;
}
_createClass(User, [{
key: "sayHi",
value: function sayHi() {
alert(this.name);
}
}]);
return User;
}();
var user = new User("John");
user.sayHi();
Run Code Online (Sandbox Code Playgroud)
所有 ES6+ 功能都可以转译为 ES5——实际上,它就是语法糖。所有“新功能”仍然可以在 ES5 中实现。我认为这被称为“One JavaScript”学说。
| 归档时间: |
|
| 查看次数: |
176 次 |
| 最近记录: |