В чем разница между объектом и объектом из класса в JavaScript? - PullRequest
1 голос
/ 09 октября 2019

Я изучаю JavaScript и Java на работе и в школе. Насколько я знаю, в Java у вас всегда есть класс, и из этого класса вы можете создавать объекты. То же самое работает в JavaScript, НО: в JavaScript можно создавать объекты без классов.

Итак, мой вопрос: в чем разница между этими двумя типами объектов в JavaScript?

class Test {
    say() {
        console.log("I'm a test.");
    }
}

let TestFromClass = new Test();

let TestFromObject = {
    say() {
        console.log("I'm also a test.");
    }
};


TestFromClass.say();    // Output: I'm a test.
TestFromObject.say();   // Output: I'm also a test.

Теперь я хотел бы узнать, есть ли в них разница или нам действительно нужны классы в JavaScript.

Ответы [ 5 ]

1 голос
/ 09 октября 2019

Объекты бывают двух форм: декларативная (буквальная) форма и построенная форма.

Литеральный синтаксис для объекта выглядит следующим образом:

var myObj = {
    key: value
    // ...
};

Созданная форма выглядиткак это:

var myObj = new Object();
myObj.key = value;

Построенная форма и буквальная форма приводят к точно такому же виду объекта. Единственное отличие состоит в том, что вы можете добавить одну или несколько пар ключ / значение к буквальному объявлению, тогда как для объектов с построенной формой вы должны добавлять свойства один за другим.

Примечание: это крайне редкоиспользовать «созданную форму» для создания объектов, как только что показано. Вы бы всегда хотели использовать буквальную синтаксическую форму. То же самое будет справедливо для большинства встроенных объектов.

PS Подробнее читайте в https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/this-object-prototypes/ch3.md

1 голос
/ 09 октября 2019

Когда вы используете new, вы создаете новый объект, внутренний прототип которого является прототипом класса. Например:

class Test {
    say() {
        console.log("I'm a test.");
    }
}

let TestFromClass = new Test();
console.log(Object.getPrototypeOf(TestFromClass) === Test.prototype);

Это полезно, когда вам нужно создать несколько объектов. Обычно такие объекты создаются, потому что они будут иметь своего рода состояние , связанное с каждым отдельным объектом, обычно в форме свойств объекта (например, объект персонажа может иметь name иage свойство).

Но если у вас нет никаких данных, связанных с экземпляром (в вашем примере, объектом TestFromClass), нет особого смысла иметь экземпляр вообще.

Если вы хотите собирать только именованные функции в структуру данных, ваш TestFromObject имеет гораздо больший смысл, чем класс.

Тем не менее, вы можете захотеть иметь класс, с которым связаны некоторые функции. это (например, say), которое не имеет ничего общего с экземпляром его данных, , в то время как может создавать экземпляр, возможно, с другими методами в прототипе. Это не редкость, и это делается с помощью функций, не связанных с экземпляром static:

class Person {
  static canEat() {
    return ['apples', 'bananas', 'carrots'];
  }
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}
const p = new Person('Bob', 99);
console.log(p.name);
console.log(Person.canEat());
0 голосов
/ 10 октября 2019

Итак, вы создали класс с именем Test, который является базовым классом. Вы добавили метод с именем say() {}.

class Test {
    say() {
        console.log("I'm a test.");
    }
}

Затем вы создали экземпляр класса Test ниже:

let TestFromClass = new Test();

И ниже вы создали простой объект JavaScriptс именем TestFromObject:

let TestFromObject = {
    say() {
        console.log("I'm also a test.");
    }
};

И да, они оба распечатают выходные данные, которые у вас есть, к их методам:

TestFromClass.say();    // Output: I'm a test.
TestFromObject.say();   // Output: I'm also a test.

Разница не начнется, пока вы не используете всю мощькласс, который вы создали, например, используя функцию cconstructor() следующим образом:

class Test {
    constructor() {

    }
    say() {
        console.log("I'm a test.");
    }
}

Теперь функция конструктора автоматически вызывается для нас, когда мы используем ключевое слово new для имени класса. С известной вам функцией конструктора также есть доступ к this, например:

class Test {
    constructor() {
      this.type = 'test';
    }
    say() {
        console.log("I'm a test.");
    }
}

, что позволяет вам сделать это:

TestFromClass.say();    // Output: I'm a test.
TestFromObject.say();   // Output: I'm also a test.
TestFromClass.type;     // Output: test

Конструктор традиционно используется для выполнения некоторых начальных операций. установка внутри класса или конкретного экземпляра класса.

Конструктор обычно используется с использованием некоторых аргументов при создании нового экземпляра класса. Возможно, вы хотите указать, что созданный вами класс Test содержит 50 вопросов. Вы можете передать объект в новый экземпляр Test следующим образом:

let TestFromClass = new Test({ questions: 50 });

Вы можете вызывать этот объект как хотите, давайте просто вызовем объект examination, и вы можете задать количество вопросов этомуexamination object.

Итак, теперь вы передаете этот объект в функцию конструктора и вызываете этот объект, examination примерно так:

class Test {
    constructor(examination) {
      this.questions = examination.questions;
      this.type = 'test';
    }
    say() {
        console.log("I'm a test.");
    }
}

let TestFromClass = new Test({ questions: 50 });

TestFromClass.say();    // Output: I'm a test.
TestFromClass.type;     // Output: test
TestFromClass.questions; // 50

Другая вещь, которую вы можете сделать с классомОбъект - это создание подкласса, который расширит функциональность вашего базового класса, а затем вы также сможете добавить к нему некоторые настраиваемые функциональные возможности.

class Test {
    constructor(examination) {
      this.questions = examination.questions;
      this.type = 'test';
    }
    say() {
        console.log("I'm a test.");
    }
}

class Quiz extends Test {

}

Так что теперь ваш тест наследует все методы, функции, свойства и т. д. которые находятся в классе Test и определяют дополнительные методы внутри него.

class Test {
    constructor(examination) {
      this.questions = examination.questions;
      this.type = 'test';
    }
    say() {
        console.log("I'm a test.");
    }
}

class Quiz extends Test {
    constructor(examination) {
    this.topic = examination.topic;
  }
}

Итак, теперь, чтобы убедиться, что функция конструктора из родительского класса также вызывается, я могу использовать ключевое слово super() вКонструктор:

class Test {
    constructor(examination) {
      this.questions = examination.questions;
      this.type = 'test';
    }
    say() {
        console.log("I'm a test.");
    }
}

class Quiz extends Test {
    constructor(examination) {
    super(examination)
    this.topic = examination.topic;
  }
}

Затем вы можете создать экземпляр этого подкласса следующим образом:

const javascript = new Quiz({topic: 'javascript', questions: 50 });

и, наконец, распечатать его:

javascript.questions; // Output: 50
0 голосов
/ 09 октября 2019

Прежде всего, класс является (почти) просто синтаксическим сахаром для прототипа:

// The class way
class Test {
  say() {
    console.log("I'm a test.");
  }
}


// The old fashioned way
function Test() {

}

Test.prototype.say = function () {
  console.log("I'm a test.");
};

Разница в обоих этих случаях при непосредственном создании объекта заключается в том, что методы принадлежат прототипу, а не напрямуюк объекту.

Когда вы используете TestFromClass.say(), он проходит по цепочке прототипов, чтобы найти метод say, в то время как TestFromObject напрямую имеет метод.

Кроме этого, нет никакой разницы.

0 голосов
/ 09 октября 2019

В чем отличие между объектом и объектом от класса в JavaScript?

По сути, их нет в общем смысле. Однако некоторые вещи могут немного отличаться:

  • Когда вы создаете объект с буквальным синтаксисом, если вы не используете специальное свойство __proto__ (только для официальных браузеров), его прототип всегда будетObject.prototype. Когда вы создаете его с помощью new X, при условии, что X является функцией конструктора, созданной с синтаксисом class, результат будет иметь прототип X.prototype.
  • Методы, определенные в литерале объекта, непосредственно помещаются вобъект. Методы в class X продолжаются X.prototype (не static), которые объект наследует .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...