импорт против __import __ () против importlib.import_module ()?

Примеры имеют очень разные результаты.

Перед рассмотрением различий следует отметить следующее:

  • Прототип конструктора обеспечивает способ совместного использования методов и значений между экземплярами через личное свойство [[Prototype]] экземпляра.
  • Функция функции задана тем, как функция вызывается или с помощью bind (не обсуждается здесь). Если функция вызывается для объекта (например, myObj.method()), то этот внутри метода ссылается на объект. Где этот не задан вызовом или с помощью bind , он по умолчанию ссылается на глобальный объект (окно в браузере) или в строгом режиме, остается неопределенным.
  • JavaScript - это объектно-ориентированный язык, то есть все объекты, включая функции.

Итак, вот фрагменты, о которых идет речь:

var A = function () {
    this.x = function () {
        //do something
    };
};

В этом случае переменной A присваивается значение, которое является ссылкой на функцию. Когда эта функция вызывается с помощью A(), функция этой функции не задается вызовом, поэтому по умолчанию используется глобальный объект, и выражение this.x эффективно window.x. В результате ссылка на выражение функции с правой стороны назначается window.x.

В случае:

var A = function () { };
A.prototype.x = function () {
    //do something
};

происходит нечто совсем другое. В первой строке переменной A присваивается ссылка на функцию. В JavaScript все объекты функций имеют свойство prototype по умолчанию, поэтому нет никакого отдельного кода для создания объекта A.prototype .

Во втором line, A.prototype.x назначается ссылка на функцию. Это создаст свойство x , если оно не существует, или назначьте новое значение, если это произойдет. Таким образом, разница с первым примером заключается в том, какое свойство объекта x участвует в выражении.

Другой пример приведен ниже. Это похоже на первое (и может быть то, о чем вы хотели спросить):

var A = new function () {
    this.x = function () {
        //do something
    };
};

В этом примере оператор new был добавлен перед выражением функции, чтобы вызвать функцию как конструктор. При вызове с new функция этой функции установлена ​​для ссылки на новый объект, чье личное свойство [[Prototype]] установлено для ссылки на общедоступный прототип конструктора . Поэтому в операторе присваивания свойство x будет создано на этом новом объекте. Когда вызывается как конструктор, функция по умолчанию возвращает свой этот объект , поэтому нет необходимости в отдельном заявлении return this;.

Чтобы проверить, что A имеет свойство x :

console.log(A.x) // function () {
                 //   //do something
                 // };

Это необычное использование new , так как единственный способ ссылки на конструктор - через A.constructor . Это было бы гораздо чаще:

var A = function () {
    this.x = function () {
        //do something
    };
};
var a = new A();

Другой способ достижения аналогичного результата - использовать сразу вызываемое выражение функции:

var A = (function () {
    this.x = function () {
        //do something
    };
}());

В этом случае A присвоено возвращаемое значение вызова функции с правой стороны. Здесь опять же, поскольку этот не задан в вызове, он будет ссылаться на глобальный объект, а this.x - эффективно window.x. Поскольку функция ничего не возвращает, A будет иметь значение undefined.

Эти различия между этими двумя подходами также проявляются, если вы сериализуете и де-сериализуете свои объекты Javascript в / от JSON. Методы, определенные на прототипе объекта, не сериализуются при сериализации объекта, что может быть удобно, если, например, вы хотите сериализовать только части данных объекта, но не его методы:

var A = function () { 
    this.objectsOwnProperties = "are serialized";
};
A.prototype.prototypeProperties = "are NOT serialized";
var instance = new A();
console.log(instance.prototypeProperties); // "are NOT serialized"
console.log(JSON.stringify(instance)); 
// {"objectsOwnProperties":"are serialized"} 

Связанные Вопросы:

Sidenote: не может быть значительной экономии памяти между двумя подходами, однако использование прототипа для совместного использования методов и свойств, скорее всего, будет использовать меньше памяти, чем каждый экземпляр имея свою собственную копию.

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

30
задан temporary_user_name 23 August 2016 в 15:40
поделиться