基于原型的类语法和JavaScript中的类语法有什么区别? [英] What is the difference between prototype-based class syntax and class syntax in JavaScript?

查看:59
本文介绍了基于原型的类语法和JavaScript中的类语法有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些可互换的语法是否可以创建JS类?我已经习惯了 class 语法,但不完全了解它们之间的区别。

Are these interchangeable syntax's to create a JS class? I'm used to the class syntax but don't understand the differences between them exactly.

function User(name) {
  this.name = name;
}

User.prototype.sayHi = function() {
  alert(this.name);
}

let user = new User("John");
user.sayHi();

vs。

class User {

 constructor(name) {
   this.name = name;
 }

 sayHi() {
   alert(this.name);
 }

}

let user = new User("John");
user.sayHi();


推荐答案

类和构造函数之间的主要区别是:

The main differences between classes and constructor functions are:


  • 没有 new 不能调用类,但其功能是构造函数可以(并且他们的是错误的)

  • Classes can’t be called without new, but functions intended as constructors can (and their this will be wrong)

'use strict';

function Foo() {
    console.log(this);
}

class Bar {
    constructor() {
        console.log(this);
    }
}

Foo();
Bar();

与构造函数相比,类可以扩展更多类型(如函数和数组)

Classes can extend more types than constructors can (like functions and arrays)

'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)'))();

类的原型是它们的父级(它们继承静态属性);构造函数的编写者通常不会为此烦恼

Classes’ prototypes are their parents (they inherit static properties); writers of constructor functions usually don’t bother with this

非类不能扩展类(因为它们不能调用父构造器–请参见第一点)

Non-classes can’t extend classes (because they can’t call the parent constructor – see the first point)

'use strict';

class Bar extends Function {}

function Foo() {
    Bar.call(this);
}

Object.setPrototypeOf(Foo, Bar);
Foo.prototype = Object.create(Bar.prototype);

void new Foo();

类的范围也像 let / const (块作用域,时间盲区,不可重声明),而不是像 var (悬挂的函数作用域)或类似的函数声明(很复杂)。

Classes are also scoped like let/const (block scope, temporal dead zone, not redeclareable) rather than like var (function scope, hoisted) or like function declarations (it’s complicated).

在您的示例中,另一个区别是 sayHi 是通过分配新的属性来定义的y而不是例如 Object.defineProperty ,因此该属性的属性与类示例中的属性不同,因为 sayHi 在前一个是可枚举的,但

In your example, an additional difference is that sayHi is defined by assigning to a new property instead of with e.g. Object.defineProperty, so the property’s properties differ from those in the class example in that sayHi is enumerable in the former but not the latter.

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);

这篇关于基于原型的类语法和JavaScript中的类语法有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆