## class expression: const Person = class { } ## class declaration: class Person { constructor(fName, bYear){ this.fName = fName; this.bYear = bYear; } calcAge(){ console.log(2024 - this.bYear); } } - constructor is a method of this class. Pass values for properties to have in objects created using this fn. - then set the properties of the object using this.xxx = xxx; - On using 'new' operator, this constructor will be called automatically and return a new object which will be stored in LHS variable as shown below. Ex. const ronald = new Person('ronald',1975); // Person { fName: 'ronald', bYear: 1975 } - Methods are written outside the constructor fn and will be added to the prototype property of the object which can be verified using devConsole. Ex. ronald.calcAge(); // 49 ronald.__proto__ === Person.prototype; // true - No commas need to be added while adding multiple methods below the constructor fn inside the class. ## Hence, the above syntax works same as constructor fn syntax but with a familiar syntax of strongly typed class based languages. ## Adding a fn explicitly to the prototype: Person.prototype.greet = function(){ console.log(`Hey ${this.fName}`); } ronald.greet(); // 'Hey ronald'
Очки результативности:
Свойства доступа: геттеры и сеттеры, т.е. fns, которые получают и устанавливают значение. Но снаружи они по-прежнему выглядят как обычные дома.
Обычные свойства называются свойствами данных.
const account = { owner: 'jonas', movements: [200,300,100,500], get latest(){ // will return an array with last value. Hence, use pop to get the value. return this.movements.slice(-1).pop(); }, set latest(mov){ this.movements.push(mov); } } account.latest; // 500 account.latest = 50; account.latest; // 50 Just like above, classes also support the getter-setter methods but acccessed like using a property syntax. These are very useful for data validation.
Бывший. Array.from() = Преобразует структуру, подобную массиву, в массив.
Array.from(document.querySelector('h1'));
Array.from(document.querySelectorAll('h1'));
Бывший. .from прикрепляется к конструктору Array, а не к свойству прототипа конструктора. Следовательно, все массивы не наследуют эту функцию.
[1,2,3].из(); // .from не является функцией
Бывший. Number.parseFloat(12) — статический метод конструктора Number, недоступный для числовых переменных.
// Static methods are not inherited. They are not added to prototype. className.fnName = function(){ console.log(this); // Entire constructor() which is calling the method console.log("JS is awesome") }; className.fnName(); // Rule = whatever object is calling the method, 'this' points to that object inside the fn. Hence its simply the entire constructor() above. //Inside class, we need to use static keyword for adding a static method. static fnName = function(){ console.log(this); // can point to the entire class defn console.log("JS is awesome") }; // Static methods and instance methods will be different from each other. // instance methods will be prototype, hence all instances can have access to them
Вручную используется для установки прототипа нашего объекта на любой объект, который мы хотим.
Будет использоваться для реализации наследования ч/б классов.
Прототипическое наследование реализовано с использованием этой функции.
Object.create возвращает пустой объект.
Работает иначе, чем конструктор fns и классы.
Тем не менее, идея прототипного наследования существует, даже без использования операторов «прототип», «конструктор()», «новый».
const PersonProto = { // This method will be looked up using __proto__ link calcAge(){ console.log(2024 - this.bYear); } }; // baba will be created, with its prototype set to PersonProto object. const baba = Object.create(PersonProto); baba; baba.name = 'Roger'; baba.bYear = '2000'; baba.calcAge();
Конструктор Fn --(.prototype)--> Person.prototype
Экземпляр объекта --(прото)--> Person.prototype
Работает так же, как в конструкторах fn или в классах
Для достижения этой цели нет необходимости в свойствеconstructor() или .prototype.
const PersonProto = { // This method will be looked up using __proto__ link calcAge(){ console.log(2024 - this.bYear); }, // Noting special with init name, its a normal fn here. // This has nothing to with ES6 constructor() // Manual way of initialzing an object. init(fName, bYear){ this.fName = fName; this.bYear = bYear; } }; // baba will be created, with its prototype set to PersonProto object. const baba = Object.create(PersonProto); baba; baba.name = 'Roger'; baba.bYear = '2000'; baba.calcAge(); baba.__proto__; // { calcAge: [Function: calcAge] } baba.__proto__ === PersonProto; //true const alice = Object.create(PersonProto); alice.init("alice", 2000); alice; // { fName: 'alice', bYear: 2000 }
Способы создания прототипного наследования:
Конструктор Fn
Классы ES6
Object.create
Все эти методы позволяют объекту искать методы своего прототипа.
Настоящих классов в JS не существует.
const Person = function(firstName, bYear){ this.firstName = firstName; this.bYear = bYear; }; Person.prototype.calcAge = function(){ console.log(2024 - this.bYear); }; const Student = function(firstName, bYear, course){ // This is the duplicate code, any change in Person won't be reflected here. this.firstName = firstName; this.bYear = bYear; this.course = course; }; Student.prototype.introduce = function(){ console.log(`My name is ${this.firstName} and I study ${this.course}`); } const matt = new Student("Matt", 2000, "CSE"); matt.introduce(); // 'My name is Matt and I study CSE'
const Person = function(firstName, bYear){ this.firstName = firstName; this.bYear = bYear; }; Person.prototype.calcAge = function(){ console.log(2024 - this.bYear); }; const Student = function(firstName, bYear, course){ // Person(firstName, bYear); -> This doesn't work because we are calling it as a regular fn call. 'new' has to be used to call this fn constructor. This fn call is simply a regular fn call, in which 'this' is set 'undefined'. Hence, an error as it cannot set firstName on undefined. // We want to set the 'this' inside this fn to be same as inside Person above. Person.call(this, firstName, bYear); this.course = course; }; Student.prototype.introduce = function(){ console.log(`My name is ${this.firstName} and I study ${this.course}`); } const matt = new Student("Matt", 2000, "CSE"); matt.introduce(); // 'My name is Matt and I study CSE'
'new' автоматически создает связь между экземпляром объекта и его прототипом через прото
Вся идея наследования заключается в том, что дочерний класс может разделять поведение родительских классов вверх по цепочке прототипов.
Прототип [Object.prototype] = ноль; // Находится на вершине цепочки прототипов.
const Person = function(firstName, bYear){ this.firstName = firstName; this.bYear = bYear; }; Person.prototype.calcAge = function(){ console.log(2024 - this.bYear); }; const Student = function(firstName, bYear, course){ Person.call(this, firstName, bYear); this.course = course; }; // Student.prototype = Person.prototype; => This doesn't work because we won't get the prototype chain, rather we will get // Constructor fn[i.e Person()] --------------> Person.prototype // Constructor fn[i.e Student()] --------------> Person.prototype // Object [Matt] __proto__: Student.prototype ---> Person.prototype // Student.prototype manually linked for lookup to Person.prototype. // This has to be done here and not after else Object.create will overwrite any of the existing methods like introduce() on it. Student.prototype = Object.create(Person.prototype); Student.prototype.introduce = function(){ console.log(`My name is ${this.firstName} and I study ${this.course}`); } const matt = new Student("Matt", 2000, "CSE"); matt.introduce(); // 'My name is Matt and I study CSE' matt.calcAge(); // 24 matt.__proto__; // Person { introduce: [Function (anonymous)] } matt.__proto__.__proto__; // { calcAge: [Function (anonymous)] } matt.__proto__.__proto__.__proto__; // [Object: null prototype] {} Student.prototype.constructor = Student; // [Function: Student] matt instanceof Student; // true matt instanceof Person; // true matt instanceof Object; // true
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3