Статья впервые опубликована вличный блог
содержание
- class
- статический метод
- статические свойства
- наследовать
- super
class
класс является синтаксическим сахаром, его нижний слой все еще сквозной构造函数создавать. Так что большинство своих функций ES5 может делать сам. Новый метод написания класса просто делает метод написания прототипа объекта более понятным и более похожим на синтаксис объектно-ориентированного программирования.
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function() {
return this.name;
}
const xiaoming = new Person('小明', 18);
console.log(xiaoming);
В приведенном выше коде используетсяES6изclassреализация следующим образом
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
return this.name;
}
}
const xiaoming = new Person('小明', 18)
console.log(xiaoming);
// { name: '小明', age: 18 }
console.log((typeof Person));
// function
console.log(Person === Person.prototype.constructor);
// true
Метод конструктора, это метод конструктора, ключевое слово this представляет объект экземпляра. Тип данных класса — это функция, а сам класс указывает на конструктор.
При определении класса не нужно добавлять функцию впереди, и не нужно разделять методы запятыми, и будет сообщено об ошибке.
Все методы класса определяются в свойстве прототипа класса.
class A {
constructor() {}
toString() {}
toValue() {}
}
// 等同于
function A () {
// constructor
};
A.prototype.toString = function() {};
A.prototype.toValue = function() {};
Вызов метода для экземпляра класса фактически вызывает метод для прототипа.
let a = new A();
a.constructor === A.prototype.constructor // true
Метод конструктора
Метод конструктора — это метод класса по умолчанию, который автоматически вызывается при создании экземпляра объекта с помощью новой команды. Класс должен иметь метод конструктора, если он не определен явно, пустой метод конструктора будет добавлен по умолчанию.
class A {
}
// 等同于
class A {
constructor() {}
}
Метод конструктора по умолчанию возвращает объект-экземпляр (то есть this), и его можно указать для возврата другого объекта.
class A {
constructor() {
return Object.create(null);
}
}
console.log((new A()) instanceof A);
// false
экземпляр класса
Свойства экземпляра определяются в прототипе (то есть в классе), если только они не определены явно в самом себе (то есть в этом объекте).
Уведомление:
- класс не имеет переменного повышения
new A(); // ReferenceError
class A {}
Потому что ES6 не поднимает объявления классов в начало кода. Причина этого условия связана с наследованием, которое должно гарантировать, что подкласс будет определен после суперкласса.
{
let A = class {};
class B extends A {}
}
Приведенный выше код не сообщит об ошибке, потому что, когда B наследует A, A уже определен. Однако, если есть повышение класса, приведенный выше код сообщит об ошибке, потому что класс будет повышен до головы кода, а команда let не повышена, поэтому, когда B наследует A, Foo еще не определен.
- указатель на это Если метод класса содержит это, по умолчанию он является экземпляром класса. Однако следует соблюдать большую осторожность, так как этот метод может сообщать об ошибках, если он используется отдельно.
статический метод
Класс эквивалентен прототипу экземпляра, и все методы, определенные в классе, будут унаследованы экземпляром. Если ключевое слово static добавлено перед методом, это означает, что метод не будет унаследован экземпляром, а будет вызываться непосредственно через класс, который называется «статическим методом».
class A {
static classMethod() {
return 'hello';
}
}
A.classMethod();
console.log(A.classMethod());
// 'hello'
const a = new A();
a.classMethod();
// TypeError: a.classMethod is not a function
AКатегорияclassMethodметод доstaticключевое слово, указывающее, что это статический метод, который можно использовать вA类上直接调用,而不是在实例上调用
в случаеaЕсли статический метод вызывается выше, будет выдана ошибка, указывающая, что метод не существует.
Если статический метод содержит ключевое слово this, this относится к классу, а не к экземпляру.
class A {
static classMethod() {
this.baz();
}
static baz() {
console.log('hello');
}
baz() {
console.log('world');
}
}
A.classMethod();
// hello
статический методclassMethodназываетсяthis.baz,здесьthisОтноситсяAкласс вместоAПример, эквивалентный позвонитьA.baz. Кроме того, как видно из этого примера, статические методы могут иметь то же имя, что и нестатические методы.
Статический метод родительского класса может быть унаследован дочерним классом.
class A {
static classMethod() {
console.log('hello');
}
}
class B extends A {}
B.classMethod() // 'hello'
статические свойства
Статические свойства относятся к свойствам самого класса, а именно к Class.propName, а не к свойствам, определенным в объекте экземпляра (этот). Он записывается путем добавления ключевого слова static перед атрибутом экземпляра.
class MyClass {
static myStaticProp = 42;
constructor() {
console.log(MyClass.myStaticProp); // 42
}
}
наследовать
Класс может реализовать наследование через ключевое слово extends
class Animal {}
class Cat extends Animal { };
Приведенный выше код определяет класс Cat,extendsKeyword наследует все атрибуты и методы класса Animal.
Но без развертывания какого-либо кода, поэтому эти два класса точно такие же, равные копии класса Animal.
Далее мы добавляем код внутри файла Cat.
class Cat extends Animal {
constructor(name, age, color) {
// 调用父类的constructor(name, age)
super(name, age);
this.color = color;
}
toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}
Как в методе-конструкторе, так и в методе toString появляется ключевое слово super, которое здесь представляет конструктор родительского класса, который используется для создания объекта this родительского класса.
Подклассы должны вызывать метод super в методе конструктора, иначе при создании нового экземпляра будет сообщено об ошибке. Это связано с тем, что объект this подкласса должен сначала быть сформирован конструктором суперкласса, чтобы получить те же атрибуты и методы экземпляра, что и суперкласс, а затем обработать его, а также собственные атрибуты и методы экземпляра подкласса. Если вы не вызовете метод super, подклассы не получат этот объект.
class Animal { /* ... */ }
class Cat extends Animal {
constructor() {
}
}
let cp = new Cat();
// ReferenceError
Cat наследует родительский класс Animal, но его конструктор не вызывает суперметод, что приводит к ошибке при создании нового экземпляра.
Если в подклассе не определен метод конструктора, этот метод будет добавлен по умолчанию, код выглядит следующим образом. То есть любой подкласс имеет метод конструктора, независимо от того, определен он явно или нет.
class Cat extends Animal {
}
// 等同于
class Cat extends Animal {
constructor(...args) {
super(...args);
}
}
Следует также отметить, что конструктор es5 может получить к нему доступ до вызова родительского конструктора, но конструктор es6 не может получить к нему доступ до вызова родительского конструктора (т.е. super).
class A {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class B extends A {
constructor(x, y, name) {
this.name = name; // ReferenceError
super(x, y);
this.name = name; // 正确
}
}
В приведенном выше коде ключевое слово this используется до того, как метод конструктора подкласса вызывает super, и результатом является ошибка, и правильно поставить его после метода super.
Статический метод родительского класса также будет унаследован дочерним классом.
class A {
static hello() {
console.log('hello world');
}
}
class B extends A {
}
B.hello() // hello world
super
Ключевое слово super может использоваться как в качестве функции, так и в качестве объекта.
super вызывается как функция
Когда super вызывается как функция, она представляет конструктор родительского класса. ES6 требует, чтобы конструктор подкласса выполнял суперфункцию один раз.
class A {}
class B extends A {
constructor() {
super();
}
}
super() в конструкторе подкласса B означает вызов конструктора родительского класса. Это обязательно, иначе движок JavaScript выдаст ошибку.
Обратите внимание, что хотя super представляет конструктор родительского класса A, он возвращает экземпляр подкласса B, то есть this внутри super ссылается на экземпляр B, поэтому super() здесь эквивалентен A.prototype.constructor.call (этот ).
class A {
constructor() {
// new.target 指向正在执行的函数
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B
существуетsuper()При выполнении он указывает на подклассBвместо конструктора родительского класса A. То есть,super()Внутреннийthisуказывает наB.
супер вызывается как объект
В обычных методах указывают на объект-прототип родительского класса; В статическом методе укажите на родительский класс.
Суперобъект вызывается в обычной функции
class A {
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p()); // 2
}
}
let b = new B();
В приведенном выше коде подклассBсредиsuper.p(), этоsuperиспользуется в качестве объекта. В настоящее время,superОбычными методами, указывая наA.prototype,такsuper.p()эквивалентноA.prototype.p().
Здесь следует отметить, что, поскольку super указывает на объект-прототип родительского класса, методы или свойства, определенные в экземпляре родительского класса, не могут быть вызваны через super.
class A {
constructor() {
this.p = 2;
}
}
class B extends A {
get m() {
return super.p;
}
}
let b = new B();
b.m // undefined
В приведенном выше коде p является атрибутом экземпляра родительского класса A, и super.p не может ссылаться на него.
Если свойство определено в объекте-прототипе родительского класса,superты можешь его достать.
class A {}
A.prototype.x = 2;
class B extends A {
constructor() {
super();
console.log(super.x) // 2
}
}
let b = new B();
В приведенном выше коде атрибут x определен вA.prototypeвыше, такsuper.xЕго значение можно получить.
суперобъект вызывается в статическом методе
При использовании в статических методах super будет указывать на родительский класс, а не на объект-прототип родительского класса.
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
const child = new Child();
child.myMethod(2); // instance 2
В приведенном выше коде super указывает на родительский класс в статическом методе и указывает на объект-прототип родительского класса в обычном методе.
Кроме того, в статическом методе подклассаsuperПри вызове метода родительского класса метод внутри методаthisУказывает на текущий подкласс, а не на экземпляр подкласса.
class A {
constructor() {
this.x = 1;
}
static print() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
static m() {
super.print();
}
}
B.x = 3;
B.m() // 3
В приведенном выше коде статический методB.mв,super.printСтатический метод, указывающий на родительский класс. в этом методеthisуказывает наB, вместоBпример.
Суммировать
- класс является синтаксическим сахаром, его нижний слой все еще сквозной
构造函数создавать. - Все методы класса определяются в свойстве прототипа класса.
- Статический метод: добавьте static перед методом, указав, что метод не будет унаследован экземпляром, а будет вызываться непосредственно через класс.
- Статическое свойство: добавьте статическое свойство перед свойством, которое относится к свойству самого класса, а не к свойству, определенному в объекте экземпляра (этот).
- Конструктор es5 может получить к нему доступ до вызова родительского конструктора, но конструктор es6 не может получить к нему доступ до вызова родительского конструктора (т.е. super).
- super
- Вызывается как функция, представляющая конструктор родительского класса
- Вызванный как объект, в обычном методе он указывает на объект-прототип родительского класса, а в статическом методе — на родительский класс.
Еще несколько вопросов для проверки
1. Что выводит следующий код
class Person {
constructor(name) {
this.name = name
}
}
const member = new Person("John")
console.log(typeof member)
Ответ: объект
Разобрать: Классы — это синтаксический сахар для конструкторов, если класс Person переписать как конструктор, то будет:
function Person() {
this.name = name
}
Вызов конструктора через new сгенерирует экземпляр конструктора Person, а выполнение ключевого слова typeof в экземпляре вернет «object», а «object» будет напечатан в приведенном выше случае.
2. Что выводит следующий код
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor
return this.newColor
}
constructor({ newColor = 'green' } = {}) {
this.newColor = newColor
}
}
const freddie = new Chameleon({ newColor: 'purple' })
freddie.colorChange('orange')
Ответ: TypeError
Разобрать: colorChange — это статический метод. Статические методы предназначены для использования только создавшим их конструктором (он же Chameleon) и не могут быть переданы экземплярам. Поскольку freddie является экземпляром, экземпляр не может использовать статические методы, поэтому генерируется ошибка TypeError.
3. Что выводит следующий код
class Person {
constructor() {
this.name = "Lydia"
}
}
Person = class AnotherPerson {
constructor() {
this.name = "Sarah"
}
}
const member = new Person()
console.log(member.name)
Ответ: «Сара».
Разобрать: Мы можем установить классы равными другим конструкторам классов/функций. В этом случае мы устанавливаем Person на AnotherPerson. Имя этого конструктора — Сара, поэтому атрибут имени нового члена экземпляра Person — Сара.
разное
Недавно был запущен 100-дневный расширенный план, в основном для того, чтобы углубиться в принципы, лежащие в основе каждой точки знаний. Добро пожаловать в общедоступный аккаунт WeChat «Звезда Мусимы». Давайте учиться вместе и пробиться в течение 100 дней.