Создание объекта в Javascript
Не вызывается почему то конструктор, пишет что не определенный конструктор хотя я ему определяю список аргументов при вызове.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Тест</title> </head> <body> <p id="result"></p> <script> let Person = { constructor:function(name,age,gender){ this.name = name; this.age = age; this.gender = gender; return this; }, greet: function(){ console.log("My name is " + this.name); } }; var tom = new Person.constructor("Вася",18,"female"); tom.greet(); </script> </body> </html> Почему я не могу использовать просто new для создания объекта, а обязательно нужно использовать Object.create.. Почему нельзя обойтись просто new для вызова конструктора? |
Надо так
let Person =function(name,age,gender){ this.name = name; this.age = age; this.gender = gender; return this; }; Person.prototype.greet= function(){ console.log("My name is " + this.name); }; var tom = new Person("Вася",18,"female"); tom.greet(); Либо так class Person { constructor (name,age,gender){ this.name = name; this.age = age; this.gender = gender; return this; } greet (){ console.log("My name is " + this.name); } } var tom = new Person("Вася",18,"female"); tom.greet(); В крайнем случае (непонятно, зачем) так let Person = { constructor:function(name,age,gender){ this.name = name; this.age = age; this.gender = gender; this.greet = Person.greet; return this; }, greet: function(){ console.log("My name is " + this.name); } }; var tom = new Person.constructor("Вася",18,"female"); tom.greet(); |
Разницы нет что с return this (я так понимаю это ссылка на объект класса)
Если убрать return this, без него также работает код, причем одинаково. Почему во втором console.log не происходит вывод 18? Ведь я передал через конструктор аргумент 18. Здесь решил попробовать наследование. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Тест</title> </head> <body> <p id="result"></p> <script> let Person =function(name,age,gender){ this.name = name; this.age = age; this.gender = gender; // return this; }; Person.prototype.greet= function(){ console.log("My name is " + this.name); }; let Son = function(age,skils){ this.skils = skils || []; Person.apply(this,arguments) } Son.prototype = Object.create(Person.prototype); Son.prototype.constructor = Son; let a = new Person("Петя",25,"female"); let b = new Son(18,["рисует","поет","водит"]); console.log(a.age); console.log(b.age + b.skils); </script> </body> </html> |
let Person =function(name,age,gender){ // какие параметры?
let Son = function(age,skils) Person.apply(this,arguments) // А что вы передаете? |
Цитата:
|
Вот еще вариант один:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script> let Person = function Pers(name, age, gender) { // Имя будет Pers this.name = name; this.age = age; this.gender = gender; }; Person.prototype.greet = function () { console.log("My name is " + this.name); } let Person2 = Person; Person2.prototype.goodbye = function () { console.log("Goodbye, " + this.name); } let Son = function (age, skils) { // Имя будет Son // Родительский конструктор вызывается до дочернего конструктора, // чтобы не было перезаписывания новых полей. Person.call(this, undefined, age, undefined); this.skils = skils || []; this.gender; } let Sunny = Son; Sunny.prototype = Object.create(Person.prototype); Sunny.prototype.constructor = Sunny; // Имя будет Son let a = new Person("Петя", 25, "female"); console.log(a); console.log(a.constructor.name); let b = new Son(18, ["рисует", "поет", "водит"]); console.log(b); console.log(b.name); </script> </body> </html> Задался еще таким вопросом. Я передал аргументы конструктору Person создав объект а, let a = new Person("Петя", 25, "female"); а как получить эти значения объекту b и вывести? Если написать так: console.log(b.name); получим undefined при выводе, а мне к примеру нужно унаследовать от родителя эти значения name, age, gender и вывести через потомка. |
Цитата:
Новой функции не будет. Функция останется одна. Только две переменные будут на нее ссылаться. И Person2.prototype это тоже самое, что Person.prototype. Один и тот же объект. Цитата:
При создании объекта b вы не передали ему значения для name и gender. Потому, что при создании объектов Son вы не предусматриваете эти параметры, а для Person передаете undefined. Вы хотите, что бы b был как то связан с а? Брал е поля? Но если вы напишите let a = new Person("Петя", 25, "male"); let a1 = new Person("Вася", 14, "male"); let a2 = new Person("Маша", 25, "female"); let b = new Son(18, ["рисует", "поет", "водит"]); То с каким из a, a1, a2 по вашему должен быть связан b? Son должен быть таким let Son = function (name, age, skils) { // Имя будет Son Person.call(this, name, age, 'male'); this.skils = skils || []; this.gender; // А это что и зачем? } |
Придумал как сделать.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script> let Person = function Pers(name, age, gender) { // Имя будет Pers this.name = name; this.age = age; this.gender = gender; }; Person.prototype.greet = function () { console.log("My name is " + this.name); } let Person2 = Person; Person2.prototype.goodbye = function () { console.log("Goodbye, " + this.name); } let Son = function (name,age,gender,skils) { // Имя будет Son // Родительский конструктор вызывается до дочернего конструктора, // чтобы не было перезаписывания новых полей. Person.call(this, name, age, gender); this.skils = skils || []; } let Sunny = Son; Sunny.prototype = Object.create(Person.prototype); Sunny.prototype.constructor = Sunny; // Имя будет Son let a = new Person("Петя", 25, "female"); console.log(a); console.log(a.constructor.name); let b = new Son(a.name,a.age,a.gender, ["рисует", "поет", "водит"]); console.log(b); console.log(b.name); </script> </body> </html> Просто засунул объект а созданный от Person в сына в качестве аргументов. let b = new Son(a.name,a.age,a.gender, ["рисует", "поет", "водит"]); Я просто хотел понять как наследовать потомку свойства и значения полученные конструктором родителя, добавляя в потомке еще свои свойства, расширяя класс родителя. |
Цитата:
Наследование предполагает, что если изменяется "родительское своиство", то оно изменяется и у самого объекта. |
Скажите, а в чем разница?
Sunny.prototype = Object.create(Person.prototype); от Sunny.prototype = Person.prototype; Оба варианта работают одинаково при выводе Внимательно перечитал вроде как и вот через консоль решил поиграться с деревом, что на что ссылается. Объект можно создать так: [PHPHTML] Teacher.prototype = Object.create( Person.prototype ); Teacher.prototype = new Person(); Teacher.prototype = { __proto__: Person.prototype }; Object.setPrototypeOf(Teacher.prototype, Person.prototype); class Teacher extends Person {}; [/PHPHTML] Вроде как все объявления работают одинаково как я понял, не важно как объявишь. Правильно я понимаю картину?Возьмем этот код: function Person(name) { this.name = name } Person.prototype.output = function(){ console.log(this.name) } function Teacher(name, skill) { Person.apply(this, [name]) this.skill = skill } Teacher.prototype = Object.create(Person.prototype) Teacher.prototype.constructor = Teacher Teacher.prototype.output = function(){ console.log(this.name, this.skill) } var t = new Teacher("john", "super man") console.log(t.constructor.name) t.output(); Когда мы объявили функцию любую у него автоматом создался prototype, скрытое свойство, зарезервированное самим движком JS. В данном коде когда мы написали function Teacher просто в коде, автоматом в скрытом свойстве [[prototype]] движка JS появилось Teacher.prototype. Когда я создал объект t t.__proto__ == Teacher.prototype Далее ссылка на родителя идет тоже через прото Teacher.prototype.__proto__ == Person.prototype А дальше Person.prototype.__proto__ == Object.prototype И далее Object.prototype.__proto__ == null И на этом конец? |
Часовой пояс GMT +3, время: 20:42. |