Каково различие между вещью var и функциональной вещью () в JavaScript?

Утверждения являются комментариями, которые не становятся устаревшими. Они документируют, какие теоретические состояния предназначаются, и какие состояния не должны происходить. Если код изменяется так состояния, позволенные изменение, разработчику скоро сообщают и должен обновить утверждение.

11
задан Justin Johnson 17 November 2009 в 03:07
поделиться

5 ответов

Статические объекты / литералы объектов

Статические объекты или объект литералы, не требуют создания экземпляра с помощью оператора new , а также ведут себя как синглтоны. Рассмотрим следующий пример:

Код:

var staticObject1 = {
 a: 123,
 b: 456
};
var staticObject2 = staticObject1;
console.log(staticObject1, staticObject2);
staticObject2.b = "hats";
console.log(staticObject1, staticObject2);

Вывод:

Object a=123 b=456  Object a=123 b=456
Object a=123 b=hats Object a=123 b=hats

Обратите внимание, что изменение staticObject2.b также повлияло на staticObject1.b . Однако это не всегда может быть желаемым эффектом. Многие библиотеки, такие как Dojo , предлагают метод клонирования объекта, который может облегчить эту ситуацию, если вы хотите сделать копию статического объекта. Продолжая предыдущий пример, рассмотрим следующее:

Код:

var staticObject3 = dojo.clone(staticObject1); // See the doc in the link above
staticObject1.a = "pants";
console.log(staticObject1, staticObject2, staticObject3);

Вывод:

Object a=pants b=hats Object a=pants b=hats Object a=123 b=hats

Обратите внимание, что значения членов staticObject1 и staticObject2 одинаковы, тогда как на staticObject3 не влияют изменения этих других объектов.

] Статические объекты также полезны для создания пространств имен проектов или библиотек, вместо того, чтобы заполнять глобальную область видимости, и способствуют совместимости, как никому не нужно.

Это полезно при создании библиотек, требующих переносимости или взаимодействия. Это можно увидеть в популярных библиотеках, таких как Dojo, YUI и ExtJs, где все или большинство методов называются dojo.examplMethod () , YUI (). ExampleMethod () или Ext.exampleMethod () соответственно.

Статические объекты также можно считать в общих чертах аналогами структуры struct в C / C ++.

Конструкторы классов / экземпляры объектов

Классы в JavaScript основаны на прототипном наследовании, которое является гораздо более сложным предметом, о котором можно прочитать о здесь , здесь и ] здесь .

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

Код:

var SomeObject = function() {
    var privateMember = "I am a private member";
    this.publicMember = "I am a public member";

    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
};

var o = new SomeObject();
console.log(typeof o.privateMember, typeof o.publicMember);
o.publicMethod();

Вывод:

undefined string
I am a private member I am a public member

Обратите внимание, что typeof o.privateMember является «неопределенным» и недоступен за пределами объекта, но изнутри .

Частные методы также могут быть созданы, но они не так просты, но по-прежнему просты в реализации. Проблема заключается в том, что значение this внутри частного метода по умолчанию равно window , и необходимо применить один из двух методов, чтобы гарантировать, что this относится к объект, с которым мы работаем, в данном случае экземпляр SomeObject . Рассмотрим следующий пример:

Код:

var SomeObject = function() {
    var privateMember = "I am a private member";
    var privateMethod = function() {
        console.log(this.publicMember);
    };

    this.publicMember = "I am a public member";
    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod.call(this);
    }
};

var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();

Вывод:

undefined function function
I am a public member

Обратите внимание, что withing privateMethodWrapper () , privatemethod был выполнен с использованием вызова и передачи в это для контекста функции. Все в порядке; однако следующий метод предпочтительнее (на мой взгляд), поскольку он упрощает область вызова и дает идентичные результаты. Предыдущий пример можно изменить на следующий:

Код:

var SomeObject = function() {
    var self          = this;
    var privateMember = "I am a private member";
    var privateMethod = function() {
        console.log(self.publicMember);
    };

    this.publicMember = "I am a public member";
    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod();
    }
};

var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();

Вывод:

undefined function function
I am a public member

Этот ответ лег в основу сообщения в моем блоге , где я привожу дополнительные примеры. Надеюсь, что это поможет;)

23
ответ дан 3 December 2019 в 02:52
поделиться

Разница в том, что объект thing1 связан с классом thing1 и унаследует (не буквально) thing1 ] prototype.

Например, позже вы можете написать

thing.prototype.initAndSend = function() { this.init(); this.send(); };

После этого вы сможете написать thing1.initAndSend () без изменения thing1 . Кроме того, thing1.constructor будет равен методу thing , тогда как {}. Constructor будет равен Object .

] Между прочим, по стандартному соглашению имена классов пишутся с заглавной буквы.

1
ответ дан 3 December 2019 в 02:52
поделиться

Функции - это объекты, а также конструкторы (их можно создать с помощью new ).

Хеш-таблицы / объекты ( {} ) являются не могут быть созданы, поэтому они обычно используются в качестве структур данных. И я не уверен, разумно ли называть их «Объектами».

0
ответ дан 3 December 2019 в 02:52
поделиться

В первом методе вы объявляете один объект. Во втором случае вы объявляете класс, из которого можно создавать (т.е. создавать) множество различных копий.

0
ответ дан 3 December 2019 в 02:52
поделиться

Случай 2 ссылается на конструкторы классов javascript . Различие заключается в том, что переменная еще не является объектом, поэтому вы не можете ссылаться на thing1.sanity. Вам нужно будет инициализировать класс, создав экземпляр указанного класса перед вызовом любых внутренних членов:

var myConstructor = function() {
    this.sanity = 0;
}

// wont work
alert(myConstructor.sanity);

// works
var thing1 = new myConstructor();
alert(thing1.sanity);

Вот статья, которая идет дальше моего быстрого примера:

Конструкторы классов против литералов объектов

6
ответ дан 3 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: