Гоголев Сергей
var student = { type: 'human', name: 'Daria', getName: function() {}, sleep: function() {} }
var lecturer = { type: 'human', name: 'Sergey', getName: function() {} talk: function() {} }
Проблема: дублирование кода
var student = {
name: 'Daria',
sleep: function () {}
}
var lecturer = {
name: 'Sergey',
talk: function () {}
}
var person = {
type: 'human',
getName: function () {}
}
student.getName();
// Daria
var student = {
name: 'Daria',
sleep: function () {}
[[Prototype]]: <ссылка на объект>
}
var student = {
name: 'Daria',
sleep: function () {}
}
var person = {
type: 'human',
getName: function () {}
}
student.__proto__ = person; // :(
Object.setPrototypeOf(student, person); // :)
var student = {
name: 'Daria',
sleep: function () {},
[[Prototype]]: <person>
}
var person = {
type: 'human',
getName: function () {}
}
var student = {
name: 'Daria',
[[Prototype]]: <person>
}
var lecturer = {
name: 'Sergey',
[[Prototype]]: <person>
}
var person = {
getName: function () {}
}
student.getName();
// Daria
lecturer.getName();
// Sergey
Объект person послужил прототипом для объекта student
Объект student делегировал свои обязанности объекту person
student.toString();
var student = {
name: 'Daria',
[[Prototype]]: <person>
}
var person = {
type: 'human',
[[Prototype]]: <Object.prototype>
}
Object.prototype = {
toString: function () {},
valueOf: function () {},
hasOwnProperty: function () {},
[[Prototype]]: null
}
Object.prototype – хранилище общих методов для всех объектов
Array.prototype = {
concat: function () {},
slice: function () {},
filter: function () {},
map: function () {},
[[Prototype]]: <Object.prototype>
}
var fruits = ['Apple', 'Banana', 'Cat'];
Object.getPrototypeOf(fruits) === Array.prototype;
// true
Function.prototype = {
call: function () {},
apply: function () {},
bind: function () {},
[[Prototype]]: <Object.prototype>
}
function sum(a, b) {
return a + b;
};
Object.getPrototypeOf(sum) === Function.prototype;
// true
var student = {
name: 'Daria',
sleep: function () {}
}
Object.setPrototypeOf(student, person);
var daria = {
name: 'Daria',
sleep: function () {}
}
var petr = {
name: 'Petr',
sleep: function () {}
}
var kirill = {
name: 'Kirill',
sleep: function () {}
}
Object.setPrototypeOf(daria, person);
Object.setPrototypeOf(petr, person);
Object.setPrototypeOf(kirill, person);
Проблема: создание новых объектов громоздкая операция
Решение: использовать конструктор объектов
function createStudent(name) {
return {
name: name,
sleep: function () {
console.log('zzzZZ ...');
}
};
}
var daria = createStudent('Daria');
var petr = createStudent('Petr');
Проблема: каждый раз создаём метод .sleep()
Решение: вынести этот метод в прототип
var student = {
sleep: function () {
console.log('zzzZZ ...');
}
}
function createStudent(name) {
var newStudent = {
name: name
};
Object.setPrototypeOf(newStudent, student)
return newStudent;
}
var daria = createStudent('Daria');
daria.sleep();
// zzzZZ ...
var petr = createStudent('Petr');
petr.sleep();
// zzzZZ ...
Любая функция вызванная оператором new
var daria = new createStudent('Daria');
function createStudent(name) {
this.name = name;
}
function createStudent(name) {
//var this = {};
this.name = name;
//return this;
}
this указывает на создаваемый объект
function createStudent(name) {
this.name = name;
}
var daria = new createStudent('Daria');
Чуть больше семантики
function student(name) {
this.name = name;
}
var daria = new student('Daria');
Чтобы отличить функцию-конструктор от обычной, их именуют с заглавной буквы.
function Student(name) {
this.name = name;
}
var daria = new Student('Daria');
function Student(name) {
this.name = name;
}
var daria = Student('Daria');
Поле создастся в глобальном объекте!
window.name === 'Daria'; // true
use strict;
TypeError: Cannot set property 'name' of undefined
function Student(name) {
this.name = name;
return {
name: 'Muahahahahaha!'
}
}
var daria = new Student('Daria');
console.log(daria.name);
// Muahahahahaha
function Student(name) {
this.name = name;
return null; // Evil mode on!
}
var daria = new Student('Daria');
console.log(daria.name);
// Daria
function Student(name) {
this.name = name;
}
var student = {
sleep: function () {
console.log('zzzZZ ...');
}
}
Object.setPrototypeOf(newStudent, student);
function Student(name) {
this.name = name;
}
Student.prototype = {
sleep: function () {}
}
function Student(name) {
// var this = {};
this.name = name;
// this.__proto__ = Student.prototype;
// return this;
}
function Student(name) {
this.name = name;
}
Student.prototype = {
sleep: function () {}
}
var daria = new Student('Daria');
var daria = {
name: 'Daria',
[[Prototype]]: <Student.prototype>
}
Прямо как Object.prototype!
daria
⇣
Student.prototype
⇣
Object.prototype
⇣
null
1. Есть у каждой функции
function kawabanga(name) {
console.log('kawabanga!');
}
2. Хранит объект
– не перечисляемое
– хранит ссылку на саму функцию
function Student(name) {
this.name = name;
}
Student.prototype.constructor === Student; // true
var daria = new Student('Daria');
daria.constructor === Student;
// true
function Student(name) {
this.name = name;
}
Student.prototype = {
sleep: function () {}
}
Проблема: уничтожаем поле .constructor
Решение: не перезаписывать .prototype
function Student(name) {
this.name = name;
}
Student.prototype.sleep = function () {
console.log('zzzZZ ...');
};
var daria = new Student('Daria');
daria.sleep();
// zzzZZ ...
var daria = new Student('Daria');
daria.constructor === Student; // true
var person = {
type: 'human',
getName: function () {
console.log(this.name);
}
}
function Person() {
this.type = 'human';
}
Person.prototype.getName = function () {
console.log(this.name);
}
function Student(name) {
this.name = name;
}
Student.prototype = Person.prototype;
Student.prototype.sleep = function () {};
var daria = new Student('Daria');
daria.getName();
// Daria
Опять перезаписали .prototype
function Student(name) {
this.name = name;
}
Student.prototype = Person.prototype;
Student.prototype.sleep = function () {};
function Lecturer(name) {
this.name = name;
}
Lecturer.prototype = Person.prototype;
var sergey = new Lecturer('Sergey');
sergey.sleep();
// zzzZZ ...
daria
⇣
Student.prototype === Person.prototype
⇣
Object.prototype
⇣
null
daria
⇣
Student.prototype
⇣
Person.prototype
⇣
Object.prototype
⇣
null
function Student(name) {
this.name = name;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.sleep = function () {};
function Lecturer(name) {
this.name = name;
}
Lecturer.prototype = Object.create(Person.prototype);
var sergey = new Lecturer('Sergey');
sergey.sleep();
TypeError: sergey.sleep is not a function
daria
⇣
Student.prototype
⇣
Person.prototype
⇣
Object.prototype
⇣
null
sergey
⇣
Lecturer.prototype
⇣
Person.prototype
⇣
Object.prototype
⇣
null
Создаёт пустой объект, прототипом которого становитсяк объект, переданный первым аргументом.
var fruit = {
isUsefull: true
}
var apple = Object.create(fruit);
apple.isUsefull; // true
Ещё один конструктор, более лучший
Object.create = function(prototype) {
// Простейший конструктор пустых объектов
function emptyFunction() {};
emptyFunction.prototype = prototype;
return new emptyFunction();
};
var apple = Object.create(fruit);
var foreverAlone = Object.create(null);
foreverAlone.hasOwnProperty; // undefined
foreverAlone
⇣
null
var fruit = {
isUsefull: true
}
var apple = Object.create(fruit, {
color: { writable: true, value: 'Green' },
shape: { writable: true, value: 'Sphere' }
});
apple.color; // Green
apple.shape; // Sphere
function Student(name) {
this.name = name;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.sleep = function () {};
Student.prototype
⇣
Person.prototype
function Person() {
this.type = 'human';
}
Person.prototype.getName = function () {
console.log(this.name);
}
function Student(name) {
this.name = name;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.sleep = function () {};
var daria = new Student('Daria');
daria
⇣
Student.prototype
⇣
Person.prototype
⇣
Object.prototype
⇣
null
Поле .name
Метод .sleep
Метод .getName
Общие методы
daria instanceof Student;
// true
daria instanceof Person;
// true
daria instanceof Object;
// true
Student.prototype.isPrototypeOf(daria);
// true
Person.prototype.isPrototypeOf(daria);
// true
Object.prototype.isPrototypeOf(daria);
// true
function Student(name) {
this.name = name;
}
function Lecturer(name) {
this.name = name;
}
Проблема: дублирование кода
Решение: вынести общий код в Person
function Person() {
this.type = 'human';
}
function Person(name) {
this.type = 'human';
this.name = name;
}
function Student(name) {
}
function Person(name) {
this.type = 'human';
this.name = name;
}
function Student(name) {
Person.call(this, name);
}
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
Student.prototype.getName = function () {
return 'Student ' + this.getName();
};
var daria = new Student('Daria');
daria.getName();
RangeError: Maximum call stack size exceeded
function Person(name) {
this.type = 'human';
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
Student.prototype.getStudentName = function () {
return 'Student ' + this.getName();
};
function Person(name) {
this.type = 'human';
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
Student.prototype.getName = function () {
return 'Student ' +
Person.prototype.getName.call(this);
};
Итак new , prototype , Object.create
Можно ли проще? Можно!
var person = {
getName: function () { return this.name; }
};
var student = Object.create(person);
student = {}
⇣
person
student.sleep = function () {};
var daria = Object.create(student);;
daria = {}
⇣
student
⇣
person
daria.name = 'Daria';
var person = {};
person.getName = function () { return this.name; }
var student = Object.create(person);
student.sleep = function () {};
var daria = Object.create(student);
daria.name = 'Daria';
var person = {};
person.getName = function () { return this.name; }
var student = Object.create(person);
student.sleep = function () {};
student.create = function (name) {
return Object.create(this, {
name: { value: name }
});
}
var daria = student.create('Daria');
new или Object.create?
function Person(name) {
this.type = 'human';
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
class Person {
constructor(name) {
this.type = 'human';
this.name = name;
}
getName() {
return this.name;
}
}
class Student extends Person {
sleep() {
console.log('zzzZZ ...');
}
}
class Student extends Person {
constructor(name) {
super(name);
},
getName() {
return 'Student' + super.getName();
}
}
var daria = new Student('Daria');
daria.getName(); // Daria
Deadline
24 ноября
02:59:59.999