Yeni classsözdizimi için, bir anda , çoğunlukla sözdizimsel şeker. (Ama biliyorsunuz, iyi bir şeker türü.) ES2015-ES2020'de classyapıcı işlevlerle yapamayacağınızı ve Reflect.construct(alt sınıflandırma Errorve Array¹ dahil ) yapabileceğiniz hiçbir şey yoktur . (O ise büyük olasılıkla ile yapabilirsiniz ES2021 bazı şeyler olacaktır classaksi yapamaz: Özel alanlar , özel yöntemler ve statik alanlar / özel statik yöntemleri .)
Dahası, classfarklı bir OOP türü mü yoksa hala JavaScript'in prototip kalıtımı mı?
Sadece süpürge ve daha uygun sözdizimi ile, her zaman yaşadım aynı prototipi miras var ise sen (yapıcı işlevleri kullanarak gibi new Foovs.). (Özellikle ES5 ve öncesinde yapamadığınız Arrayveya türetme durumunda Error. Artık Reflect.construct[ spec , MDN ] ile yapabilirsiniz, ancak eski ES5 tarzı ile yapamazsınız.)
Kullanarak değiştirebilir miyim .prototype?
Evet, yine de değiştirebilirsiniz. prototype sınıfı oluşturduktan sonra, sınıfın yapıcısındaki nesneyi . Örneğin, bu tamamen yasaldır:
class Foo {
constructor(name) {
this.name = name;
}
test1() {
console.log("test1: name = " + this.name);
}
}
Foo.prototype.test2 = function() {
console.log("test2: name = " + this.name);
};
Hızın faydaları var mı?
Bunun için belirli bir deyim sağlayarak, sanırım mümkün motoru daha iyi bir iş Optimizasyon konusunda yapmak mümkün olabilir. Ancak zaten optimize etmede çok başarılılar, önemli bir fark beklemiyorum.
ES2015'in (ES6) faydaları nelerdir? class sözdizimi sağlar?
Kısaca: İlk etapta yapıcı işlevleri kullanmıyorsanız, Object.create veya benzeri classşeyler sizin için yararlı olmaz.
Yapıcı işlevleri kullanırsanız, class :
Sözdizimi daha basittir ve daha az hataya açıktır.
Bu var çok daha kolay (ve yine daha az hata) eski ile daha yeni sözdizimi kullanılarak miras hiyerarşileri kurmak.
classsizi newyapıcı işleviyle kullanmamanın yaygın hatasına karşı korur (yapıcının bir istisna atmasını sağlayarakthis için geçerli bir nesne , ).
Bir yöntemin üst prototip sürümünü çağırmak, yeni sözdizimiyle eskisinden ( veya super.method()yerine ) çok daha basittir .ParentConstructor.prototype.method.call(this)Object.getPrototypeOf(Object.getPrototypeOf(this)).method.call(this)
İşte bir hiyerarşi için sözdizimi karşılaştırması:
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() {
}
}
Misal:
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());
vs.
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() {
};
Canlı Örnek:
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());
Gördüğünüz gibi, yanlış yapılması kolay ve yeniden yazması sıkıcı olan birçok tekrarlanan ve ayrıntılı şey (bu yüzden bunu yapmak için bir senaryo yazdım) , geri döndüm).
¹ "ES2015-ES2018'de, classyapıcı işlevlerle yapamayacağınızı ve Reflect.construct(alt sınıflandırma dahil) yapabileceğiniz hiçbir şey yoktur.Error veArray ) "
Misal:
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;
}