14.01.2021, 22:20
|
Аспирант
|
|
Регистрация: 01.12.2020
Сообщений: 55
|
|
Создание объекта в 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 для вызова конструктора?
|
|
15.01.2021, 07:17
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
Надо так
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();
Последний раз редактировалось voraa, 15.01.2021 в 07:24.
|
|
15.01.2021, 21:48
|
Аспирант
|
|
Регистрация: 01.12.2020
Сообщений: 55
|
|
Разницы нет что с 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>
Последний раз редактировалось denis_alekss, 15.01.2021 в 23:32.
|
|
15.01.2021, 23:48
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
let Person =function(name,age,gender){ // какие параметры?
let Son = function(age,skils)
Person.apply(this,arguments) // А что вы передаете?
|
|
16.01.2021, 15:58
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Сообщение от denis_alekss
|
Разницы нет что с return this (я так понимаю это ссылка на объект класса)
Если убрать return this, без него также работает код, причем одинаково.
|
https://learn.javascript.ru/construc...ruktora-return
|
|
17.01.2021, 23:52
|
Аспирант
|
|
Регистрация: 01.12.2020
Сообщений: 55
|
|
Вот еще вариант один:
<!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 и вывести через потомка.
|
|
18.01.2021, 09:54
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
Сообщение от denis_alekss
|
let Person2 = Person;
Person2.prototype.goodbye = function () {
console.log("Goodbye, " + this.name);
}
|
Это зачем?
Новой функции не будет.
Функция останется одна. Только две переменные будут на нее ссылаться.
И Person2.prototype это тоже самое, что Person.prototype. Один и тот же объект.
Сообщение от denis_alekss
|
а как получить эти значения объекту b и вывести?
|
Никак. Это разные объекты.
При создании объекта 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; // А это что и зачем?
}
Последний раз редактировалось voraa, 18.01.2021 в 10:21.
|
|
18.01.2021, 23:42
|
Аспирант
|
|
Регистрация: 01.12.2020
Сообщений: 55
|
|
Придумал как сделать.
<!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, ["рисует", "поет", "водит"]);
Я просто хотел понять как наследовать потомку свойства и значения полученные конструктором родителя, добавляя в потомке еще свои свойства, расширяя класс родителя.
|
|
19.01.2021, 10:11
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
Сообщение от denis_alekss
|
как наследовать потомку свойства и значения полученные конструктором родителя
|
Здесь нет никакого наследования. Просто два разных объекта, у которых некоторые свойства совпадают.
Наследование предполагает, что если изменяется "родительское своиство", то оно изменяется и у самого объекта.
|
|
25.01.2021, 22:41
|
Аспирант
|
|
Регистрация: 01.12.2020
Сообщений: 55
|
|
Скажите, а в чем разница?
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
И на этом конец?
Последний раз редактировалось denis_alekss, 25.01.2021 в 23:56.
|
|
|
|