Какой способ лучше всего подходит для создания объекта в 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 ; 
};
  1. Конструктор Literal
var person = { 
  name : "Anand",
  getName : function (){
   return this.name
  } 
} 
  1. function Конструктор
function Person(name){
  this.name = name
  this.getName = function(){
    return this.name
  } 
} 
  1. Прототип
function Person(){};

Person.prototype.name = "Anand";
  1. Функция/комбинация прототипов
function Person(name){
  this.name = name;
} 
Person.prototype.getName = function(){
  return this.name
} 
  1. 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.