Какой способ лучше всего подходит для создания объекта в JavaScript? Нужно ли 'var' перед свойством объекта?
До сих пор я видел три способа создания объекта в JavaScript. Какой способ лучше всего подходит для создания объекта и почему?
Я также видел, что во всех этих примерах ключевое слово var
не используется перед свойством - почему? Не обязательно ли объявлять var
перед именем свойства, так как упоминалось, что свойства являются переменными?
Во втором и третьем способе имя объекта пишется в верхнем регистре, тогда как в первом случае имя объекта пишется в нижнем регистре. Какой случай мы должны использовать для имени объекта?
Первый способ:
function person(fname, lname, age, eyecolor){
this.firstname = fname;
this.lastname = lname;
this.age = age;
this.eyecolor = eyecolor;
}
myFather = new person("John", "Doe", 50, "blue");
document.write(myFather.firstname + " is " + myFather.age + " years old.");
Второй способ:
var Robot = {
metal: "Titanium",
killAllHumans: function(){
alert("Exterminate!");
}
};
Robot.killAllHumans();
Третий способ - объекты JavaScript, использующие синтаксис массива:
var NewObject = {};
NewObject['property1'] = value;
NewObject['property2'] = value;
NewObject['method'] = function(){ /* function code here */ }
Ответы
Ответ 1
Нет лучшего способа, это зависит от вашего варианта использования.
- Используйте способ 1, если вы хотите создать несколько похожих объектов. В вашем примере
Person
(имя должно начинаться с заглавной буквы) называется функцией конструктора. Это похоже на классы на других языках ОО. - Используйте способ 2, если вам нужен только один объект (например, синглтон). Если вы хотите, чтобы этот объект наследовал от другого, тогда вы должны использовать функцию конструктора.
- Используйте способ 3, если вы хотите инициализировать свойства объекта в зависимости от других его свойств или если у вас есть динамические имена свойств.
Обновление: как просили примеры для третьего способа.
Зависимые свойства:
Следующее не работает, так как this
не относится к book
. Невозможно инициализировать свойство значениями других свойств в литерале объекта:
var book = {
price: somePrice * discount,
pages: 500,
pricePerPage: this.price / this.pages
};
вместо этого вы можете сделать:
var book = {
price: somePrice * discount,
pages: 500
};
book.pricePerPage = book.price / book.pages;
// or book['pricePerPage'] = book.price / book.pages;
Динамические имена свойств:
Если имя свойства хранится в некоторой переменной или создается с помощью какого-либо выражения, то вам нужно использовать скобочные обозначения:
var name = 'propertyName';
// the property will be 'name', not 'propertyName'
var obj = {
name: 42
};
// same here
obj.name = 42;
// this works, it will set 'propertyName'
obj[name] = 42;
Ответ 2
Существует несколько способов определения функции. Это полностью зависит от вашего требования. Ниже приведены несколько стилей: -
- Конструктор объектов
- Конструктор Literal
- Функциональный
- Protoype Based
- Функция и прототип
- Синглтон на основе
Примеры:
var person = new Object();
person.name = "Anand",
person.getName = function(){
return this.name ;
};
- Конструктор Literal
var person = {
name : "Anand",
getName : function (){
return this.name
}
}
- function Конструктор
function Person(name){
this.name = name
this.getName = function(){
return this.name
}
}
- Прототип
function Person(){};
Person.prototype.name = "Anand";
- Функция/комбинация прототипов
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
return this.name
}
- Singleton
var person = new function(){
this.name = "Anand"
}
Вы можете попробовать его на консоли, если у вас есть путаница.
Ответ 3
Нет никакого "лучшего способа" для создания объекта. Каждый способ имеет преимущества в зависимости от вашего варианта использования.
Шаблон конструктора (функция, связанная с оператором new
для его вызова) предоставляет возможность использования прототипного наследования, тогда как другие способы этого не делают. Итак, если вы хотите прототипное наследование, то функция конструктора - прекрасный способ пойти.
Однако, если вы хотите прототипное наследование, вы можете использовать Object.create
, что делает наследование более очевидным.
Создание объектного литерала (ex: var obj = {foo: "bar"};
) отлично работает, если у вас есть все свойства, которые вы хотите установить под рукой во время создания.
Для установки свойств позже синтаксис NewObject.property1
обычно предпочтительнее NewObject['property1']
, если вы знаете имя свойства. Но последнее полезно, когда у вас на самом деле нет имени свойства раньше времени (например: NewObject[someStringVar]
).
Надеюсь, это поможет!
Ответ 4
Я думаю, это зависит от того, что вы хотите. Для простых объектов, я думаю, вы могли бы использовать второй метод. Когда ваши объекты становятся больше и вы планируете использовать похожие объекты, я предполагаю, что первый метод будет лучше. Таким образом, вы также можете расширить его с помощью прототипов.
Пример:
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.getCircumference = function() {
return Math.PI * 2 * this.radius;
};
Circle.prototype.getArea = function() {
return Math.PI * this.radius * this.radius;
}
Я не большой поклонник третьего метода, но он действительно полезен для динамического редактирования свойств, например var foo='bar'; var bar = someObject[foo];
.
Ответ 5
Есть много способов создать ваши объекты в JavaScript. Использование функции конструктора для создания объекта или буквенной нотации объекта использует alot в JavaScript. Кроме того, создавая экземпляр Object, а затем добавляя к нему свойства и методы, существует три распространенных способа создания объектов в JavaScript.
Конструктивные функции
Существуют встроенные функции конструктора, которые мы все время от времени можем использовать, такие как Date(), Number(), Boolean() и т.д., Все функции конструктора начинаются с заглавной буквы, в то же время мы можем создавать собственные функции конструктора в JavaScript как это:
function Box (Width, Height, fill) {
this.width = Width; // The width of the box
this.height = Height; // The height of the box
this.fill = true; // Is it filled or not?
}
и вы можете вызвать его, просто используя new(), чтобы создать новый экземпляр конструктора, создать что-то вроде ниже и вызвать функцию конструктора с заполненными параметрами:
var newBox = new Box(8, 12, true);
Объектные литералы
Использование объектных литералов очень часто используется при создании объекта в JavaScript, это пример создания простого объекта, вы можете назначить что угодно для свойств объекта, если они определены:
var person = {
name: "Alireza",
surname: "Dezfoolian"
nose: 1,
feet: 2,
hands: 2,
cash: null
};
макетирования
После создания объекта вы можете создать для него больше прототипов, например, добавив цвет в наш бокс, мы можем сделать это:
Box.prototype.colour = 'red';
Ответ 6
Конечно, есть лучший способ. Объекты в javascript имеют перечисляемые и не перечисляемые свойства.
var empty = {};
console.log(empty.toString);
// . function toString(){...}
console.log(empty.toString());
// . [object Object]
В приведенном выше примере вы можете видеть, что пустой объект на самом деле имеет свойства.
Хорошо, сначала давайте посмотрим, что является лучшим способом:
var new_object = Object.create(null)
new_object.name = 'Roland'
new_object.last_name = 'Doda'
//etc
console.log("toString" in new_object) //=> false
В приведенном выше примере журнал выдаст false.
Теперь давайте посмотрим, почему другие способы создания объектов являются неправильными.
//Object constructor
var object = new Object();
console.log("toString" in object); //=> true
//Literal constructor
var person = {
name : "Anand",
getName : function (){
return this.name
}
}
console.log("toString" in person); //=> true
//function Constructor
function Person(name){
this.name = name
this.getName = function(){
return this.name
}
}
var person = new Person ('landi')
console.log("toString" in person); //=> true
//Prototype
function Person(){};
Person.prototype.name = "Anand";
console.log("toString" in person); //=> true
//Function/Prototype combination
function Person2(name){
this.name = name;
}
Person2.prototype.getName = function(){
return this.name
}
var person2 = new Person2('Roland')
console.log("toString" in person2) //=> true
Как вы можете видеть выше, все примеры войти true.Which означает, что если у Вас есть случай, что у вас есть for in
цикле, чтобы увидеть, если объект имеет свойство приведет вас к неверным результатам, вероятно.
Обратите внимание, что лучше всего это нелегко. Вам нужно построчно определять все свойства объекта. Другие способы более просты и требуют меньше кода для создания объекта, но вы должны знать об этом в некоторых случаях. Кстати, я всегда использую "другие способы", и одним из способов предупреждения выше, если вы не используете лучший способ, является:
for (var property in new_object) {
if (new_object.hasOwnProperty(property)) {
// ... this is an own property
}
}
Ответ 7
В основном есть 3 способа создания Objects-
Самый простой из них - использование литералов объектов.
const myObject = {}
Хотя этот метод является самым простым, но имеет недостаток, т.е. Если ваш объект имеет поведение (функции в нем), то в будущем, если вы захотите внести в него какие-либо изменения, вам придется изменить его во всех объектах.
Так что в этом случае лучше использовать функции Factory или Constructor. (Любой, кто вам нравится)
Фабричные функции - это те функции, которые возвращают объект .e. g-
function factoryFunc(exampleValue){
return{
exampleProperty: exampleValue
}
}
Функции конструктора - это те функции, которые присваивают свойства объектам с помощью ключевого слова this. E. g-
function constructorFunc(exampleValue){
this.exampleProperty= exampleValue;
}
const myObj= new constructorFunc(1);
Ответ 8
В то время как многие люди здесь говорят, что нет лучшего способа создания объектов, существует разумное объяснение, почему существует так много способов создания объектов в JavaScript, начиная с 2019 года, и это связано с прогрессом JavaScript на разных итерациях EcmaScript выпускает начиная с 1997 года.
До ECMAScript 5 существовало только два способа создания объектов: функция конструктора или литеральная запись (лучшая альтернатива new Object()). С помощью нотации функции конструктора вы создаете объект, который может быть создан в нескольких экземплярах (с новым ключевым словом), в то время как буквенная нотация доставляет один объект, например, одиночный.
// constructor function
function Person() {};
// literal notation
var Person = {};
Независимо от используемого вами метода, объекты JavaScript являются просто свойствами пар ключ-значение:
// Method 1: dot notation
obj.firstName = 'Bob';
// Method 2: bracket notation. With bracket notation, you can use invalid characters for a javascript identifier.
obj['lastName'] = 'Smith';
// Method 3: Object.defineProperty
Object.defineProperty(obj, 'firstName', {
value: 'Bob',
writable: true,
configurable: true,
enumerable: false
})
// Method 4: Object.defineProperties
Object.defineProperties(obj, {
firstName: {
value: 'Bob',
writable: true
},
lastName: {
value: 'Smith',
writable: false
}
});
В ранних версиях JavaScript единственным реальным способом имитации наследования на основе классов было использование функций конструктора. функция конструктора - это специальная функция, которая вызывается с ключевым словом "new". По соглашению, идентификатор функции пишется с заглавной буквы, но не требуется. Внутри конструктора мы ссылаемся на ключевое слово this, чтобы добавить свойства к объекту, который неявно создается функцией конструктора. Функция конструктора неявно возвращает новый объект с заполненными свойствами обратно вызывающей функции неявно, если только вы явно не используете ключевое слово return и не возвращаете что-то еще.
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.sayName = function(){
return "My name is " + this.firstName + " " + this.lastName;
}
}
var bob = new Person("Bob", "Smith");
bob instanceOf Person // true
Существует проблема с методом sayName. Как правило, в языках программирования на основе объектно-ориентированных классов вы используете классы как фабрики для создания объектов. Каждый объект будет иметь свои собственные переменные экземпляра, но у него будет указатель на методы, определенные в проекте класса. К сожалению, при использовании функции конструктора JavaScript каждый раз, когда она вызывается, она определяет новое свойство sayName для вновь создаваемого объекта. Таким образом, у каждого объекта будет свое уникальное свойство sayName. Это будет потреблять больше ресурсов памяти.
В дополнение к увеличению ресурсов памяти, определение методов внутри функции конструктора исключает возможность наследования. Опять же, метод будет определен как свойство вновь создаваемого объекта, а не другого объекта, поэтому наследование не может работать как. Следовательно, JavaScript предоставляет цепочку прототипов как форму наследования, что делает JavaScript языком прототипов.
Если у вас есть родительский объект, и родительский объект разделяет многие свойства дочернего элемента, тогда дочерний элемент должен наследовать эти свойства. До ES5 это было сделано следующим образом:
function Parent(eyeColor, hairColor) {
this.eyeColor = eyeColor;
this.hairColor = hairColor;
}
Parent.prototype.getEyeColor = function() {
console.log('has ' + this.eyeColor);
}
Parent.prototype.getHairColor = function() {
console.log('has ' + this.hairColor);
}
function Child(firstName, lastName) {
Parent.call(this, arguments[2], arguments[3]);
this.firstName = firstName;
this.lastName = lastName;
}
Child.prototype = Parent.prototype;
var child = new Child('Bob', 'Smith', 'blue', 'blonde');
child.getEyeColor(); // has blue eyes
child.getHairColor(); // has blonde hair
То, как мы использовали прототип цепочки выше, имеет причуду. Поскольку прототип является действующей ссылкой, изменяя свойство одного объекта в цепочке прототипов, вы также изменили бы то же свойство другого объекта. Очевидно, что изменение дочернего унаследованного метода не должно изменять родительский метод. Object.create решил эту проблему, используя полифилл. Таким образом, с помощью Object.create вы можете безопасно изменять дочернее свойство в цепочке прототипов, не затрагивая родительское свойство в цепочке прототипов.
ECMAScript 5 представил Object.create для решения вышеупомянутой ошибки в функции конструктора для создания объекта. Метод Object.create() СОЗДАЕТ новый объект, используя существующий объект в качестве прототипа вновь созданного объекта. Поскольку новый объект создается, у вас больше не возникает проблема, при которой изменение дочернего свойства в цепочке прототипов будет изменять родительскую ссылку на это свойство в цепочке.
var bobSmith = {
firstName: "Bob",
lastName: "Smith",
sayName: function(){
return "My name is " + this.firstName + " " + this.lastName;
}
}
var janeSmith = Object.create(bobSmith, {
firstName : { value: "Jane" }
})
console.log(bobSmith.sayName()); // My name is Bob Smith
console.log(janeSmith.sayName()); // My name is Jane Smith
janeSmith.__proto__ == bobSmith; // true
janeSmith instanceof bobSmith; // Uncaught TypeError: Right-hand side of 'instanceof' is not callable. Error occurs because bobSmith is not a constructor function.
До ES6 здесь использовался общий шаблон для создания конструкторов функций и Object.create:
const View = function(element){
this.element = element;
}
View.prototype = {
getElement: function(){
this.element
}
}
const SubView = function(element){
View.call(this, element);
}
SubView.prototype = Object.create(View.prototype);
Теперь Object.create в сочетании с функциями конструктора широко используются для создания и наследования объектов в JavaScript. Тем не менее, ES6 представил концепцию классов, которые в основном являются синтаксическим сахаром по сравнению с существующим наследованием на основе прототипов JavaScript. Синтаксис класса не вводит новую объектно-ориентированную модель наследования в JavaScript. Таким образом, JavaScript остается прототипом языка.
Классы ES6 значительно упрощают наследование. Нам больше не нужно вручную копировать функции прототипа родительского класса и сбрасывать конструктор дочернего класса.
// create parent class
class Person {
constructor (name) {
this.name = name;
}
}
// create child class and extend our parent class
class Boy extends Person {
constructor (name, color) {
// invoke our parent constructor function passing in any required parameters
super(name);
this.favoriteColor = color;
}
}
const boy = new Boy('bob', 'blue')
boy.favoriteColor; // blue
В целом, эти 5 различных стратегий создания объектов в JavaScript совпали с развитием стандарта EcmaScript.