새로운 class
구문를 들면, 지금은 주로 문법 설탕. (하지만 좋은 종류의 설탕이 있습니다.) ES2015-ES2020 class
에는 생성자 함수 Reflect.construct
(서브 클래 싱 Error
및 Array
¹ 포함)로 할 수없는 작업이 없습니다 . (그것은 이다 아마 당신이 할 수있는 ES2021에 몇 가지가있을 것입니다 class
당신이 그렇지 않으면 할 수없는 : private 필드 , 개인 방법 및 정적 필드 / 개인 정적 방법 .)
또한 class
다른 종류의 OOP입니까 아니면 여전히 JavaScript의 프로토 타입 상속입니까?
생성자 함수 ( , 등)를 사용 하는 것을 좋아 한다면 더 깔끔하고 편리한 구문으로 우리가 항상 가지고 있었던 것과 동일한 프로토 타입 상속 new Foo
입니다. (특히 ES5 이전 버전에서는 할 수 없었던 Array
or Error
에서 파생 된 경우입니다 . 이제 Reflect.construct
[ spec , MDN ]으로는 가능하지만 이전 ES5 스타일에서는 불가능합니다.)
을 사용하여 수정할 수 있습니까 .prototype
?
예, prototype
클래스를 만든 후에도 클래스 생성자 에서 개체를 수정할 수 있습니다 . 예를 들어, 이것은 완벽하게 합법적입니다.
class Foo {
constructor(name) {
this.name = name;
}
test1() {
console.log("test1: name = " + this.name);
}
}
Foo.prototype.test2 = function() {
console.log("test2: name = " + this.name);
};
속도 이점이 있습니까?
이것에 대한 특정 관용구를 제공함으로써, 나는 그것의 가정 가능한 엔진이 더 나은 작업 최적화를 할 수있을 수 있음. 그러나 그들은 이미 최적화에 매우 능숙합니다. 나는 큰 차이를 기대하지 않습니다.
ES2015 (ES6) class
구문은 어떤 이점을 제공합니까?
간단히 말해서 : 처음에 생성자 함수를 사용하지 않는 경우 선호 Object.create
하거나 유사한 class
것은 유용하지 않습니다.
생성자 함수를 사용하는 경우 다음과 같은 이점이 있습니다 class
.
구문이 더 간단하고 오류가 덜 발생합니다.
그건 훨씬 더 쉽게 (다시, 더 적은 오류가 발생하기 쉬운) 이전보다 새로운 구문을 사용하여 상속 계층 구조를 설정합니다.
class
new
생성자 함수와 함께 사용하지 못하는 일반적인 오류로부터 사용자를 보호합니다 (생성자에 this
대해 유효한 개체가 아닌 경우 생성자가 예외를 throw하도록 함 ).
새 구문을 사용하면 부모 프로토 타입 버전의 메서드를 호출하는 것이 이전 ( 또는 super.method()
대신) 보다 훨씬 간단합니다 .ParentConstructor.prototype.method.call(this)
Object.getPrototypeOf(Object.getPrototypeOf(this)).method.call(this)
다음은 계층 구조에 대한 구문 비교입니다.
class Person {
constructor(first, last) {
this.first = first;
this.last = last;
}
personMethod() {
}
}
class Employee extends Person {
constructor(first, last, position) {
super(first, last);
this.position = position;
}
employeeMethod() {
}
}
class Manager extends Employee {
constructor(first, last, position, department) {
super(first, last, position);
this.department = department;
}
personMethod() {
const result = super.personMethod();
return result;
}
managerMethod() {
}
}
예:
class Person {
constructor(first, last) {
this.first = first;
this.last = last;
}
personMethod() {
return `Result from personMethod: this.first = ${this.first}, this.last = ${this.last}`;
}
}
class Employee extends Person {
constructor(first, last, position) {
super(first, last);
this.position = position;
}
personMethod() {
const result = super.personMethod();
return result + `, this.position = ${this.position}`;
}
employeeMethod() {
}
}
class Manager extends Employee {
constructor(first, last, position, department) {
super(first, last, position);
this.department = department;
}
personMethod() {
const result = super.personMethod();
return result + `, this.department = ${this.department}`;
}
managerMethod() {
}
}
const m = new Manager("Joe", "Bloggs", "Special Projects Manager", "Covert Ops");
console.log(m.personMethod());
대
var Person = function(first, last) {
if (!(this instanceof Person)) {
throw new Error("Person is a constructor function, use new with it");
}
this.first = first;
this.last = last;
};
Person.prototype.personMethod = function() {
};
var Employee = function(first, last, position) {
if (!(this instanceof Employee)) {
throw new Error("Employee is a constructor function, use new with it");
}
Person.call(this, first, last);
this.position = position;
};
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.employeeMethod = function() {
};
var Manager = function(first, last, position, department) {
if (!(this instanceof Manager)) {
throw new Error("Manager is a constructor function, use new with it");
}
Employee.call(this, first, last, position);
this.department = department;
};
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;
Manager.prototype.personMethod = function() {
var result = Employee.prototype.personMethod.call(this);
return result;
};
Manager.prototype.managerMethod = function() {
};
라이브 예 :
var Person = function(first, last) {
if (!(this instanceof Person)) {
throw new Error("Person is a constructor function, use new with it");
}
this.first = first;
this.last = last;
};
Person.prototype.personMethod = function() {
return "Result from personMethod: this.first = " + this.first + ", this.last = " + this.last;
};
var Employee = function(first, last, position) {
if (!(this instanceof Employee)) {
throw new Error("Employee is a constructor function, use new with it");
}
Person.call(this, first, last);
this.position = position;
};
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.personMethod = function() {
var result = Person.prototype.personMethod.call(this);
return result + ", this.position = " + this.position;
};
Employee.prototype.employeeMethod = function() {
};
var Manager = function(first, last, position, department) {
if (!(this instanceof Manager)) {
throw new Error("Manager is a constructor function, use new with it");
}
Employee.call(this, first, last, position);
this.department = department;
};
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;
Manager.prototype.personMethod = function() {
var result = Employee.prototype.personMethod.call(this);
return result + ", this.department = " + this.department;
};
Manager.prototype.managerMethod = function() {
};
var m = new Manager("Joe", "Bloggs", "Special Projects Manager", "Covert Ops");
console.log(m.personMethod());
보시다시피, 틀리기 쉽고 재 입력하기 지루한 반복적이고 장황한 내용이 많이 있습니다 (이것이 제가 스크립트를 작성 했던 이유 입니다.
¹ "ES2015-ES2018 class
에는 생성자 함수 및 Reflect.construct
(하위 클래스 Error
및 포함 Array
)로 할 수없는 작업이 없습니다. "
예:
function MyError(...args) {
return Reflect.construct(Error, args, this.constructor);
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;
MyError.prototype.myMethod = function() {
console.log(this.message);
};
function outer() {
function inner() {
const e = new MyError("foo");
console.log("Callng e.myMethod():");
e.myMethod();
console.log(`e instanceof MyError? ${e instanceof MyError}`);
console.log(`e instanceof Error? ${e instanceof Error}`);
throw e;
}
inner();
}
outer();
.as-console-wrapper {
max-height: 100% !important;
}