Конструкторы JavaScript с использованием литеральной нотации JavaScript - PullRequest
16 голосов
/ 03 марта 2011

Каков наилучший способ построения конструкторов в JavaScript с использованием литеральной нотации объектов?

var myObject = {
 funca : function() {
  //...
 },

 funcb : function() {
  //...
 }
};

Я хочу иметь возможность вызывать

var myVar = new myObject(...);

и передавать аргументы конструкторуфункция внутри myObject.

Ответы [ 6 ]

46 голосов
/ 03 марта 2011

Это , а не"нотация JSON", это JavaScript буквенная нотация объекта . JSON является лишь подмножеством буквенной нотации объектов JS, но кроме того, что они похожи, они не имеют ничего общего. JSON используется как формат обмена данными , как XML.

Невозможно, что вы хотите сделать.

var myObject = {};

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

Однако вы можете создать функцию конструктора и добавить методы к ее прототипу:

function MyObject(arg1, arg2) {
    // this refers to the new instance
    this.arg1 = arg1;
    this.arg2 = arg2;

    // you can also call methods
    this.funca(arg1);
}

MyObject.prototype = {
 funca : function() {
  // can access `this.arg1`, `this.arg2`
 },

 funcb : function() {
  // can access `this.arg1`, `this.arg2`
 }
};

Каждый объект, который вы создаете с помощью new MyObject(), будет наследовать свойства прототипа (фактически, экземпляры просто получают ссылку на объект-прототип).

Подробнее об объектах JavaScript и наследовании:


Update2:

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

7 голосов
/ 03 марта 2011

Сделайте объект функцией, например так:

var myObject = function(arg1){
  this.funca = function(){
    //...
  };
  this.funcb = function(){
    //...
  };
  this.constructor = function(obj){
    alert('constructor! I can now use the arg: ' + obj.name);
  };
  this.constructor(arg1);
};

// Use the object, passing in an initializer:
var myVar = new myObject({ name: 'Doug'});
3 голосов
/ 11 февраля 2014
var myObject = function(arg){
    return{
        constructor: function(arg){
            //...
            return this;
        },

        funca: function(){
            //...
        },

        funcb: function(){
            //...
        }
    }.constructor(arg);
};

//...

var myVar = new myObject("...");
3 голосов
/ 29 ноября 2012

Извините за опоздание на вечеринку, но ... я думаю, что это невозможно немного ограничивает, в зависимости от того, как вы интерпретируете вопрос ОП и последующие комментарии.

Предполагая, что OP хотел получить преимущества пространства имен, которые буквальная нотация объекта может принести библиотеке, но также хотел иметь некоторые "классы" для использования в этой структуре. Не могли бы вы использовать что-то из этой формы для объединения шаблонов конструктора в структуру библиотеки пространств имен пространственной нотации литералов объектов?

var myNamespace = {
    aProperty: "A value",

    aMethod: function () { return "A method result"; },

    onePlusOneEquals: function () {
        return new myNamespace.classes.NumberStuff(1, 1).added;
    },

    classes: {
        ClassA: function () {
            this.propertyOne = null;
            this.methodOne = function (param) {
                return "The method was passed " + param;
            }
        },

        NumberStuff: function (argOne, argTwo) {
            this.added      = argOne + argTwo;
            this.subtracted = argOne - argTwo;
        }
    }
};

myNamespace.classes.ClassA.prototype.methodTwo = function () { return "At least this one's not bloating our memory footprint with every ClassA created..."; };

...

var anObj = new myNamespace.classes.ClassA();
alert(anObj.methodOne("the parcel")); // "The method was passed the parcel"
alert(myNamespace.onePlusOneEquals()); //2

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

2 голосов
/ 26 февраля 2015
var myObject = {
 funca : function() {
  //...
 },

 funcb : function() {
  //...
 }
};

вы не можете создать новый объект выше этим способом

var myVar = new myObject(...);

, но вы можете достичь того же с помощью конструкции ниже,

var myVar = Object.create(myObject );
2 голосов
/ 27 января 2012

Самый простой способ, который я знаю:

function test(arg1, arg2) {
  var1 = arg1;
  var2 = arg2;
  return {
    var3 : var1, // json can access var1
    var4 : var2 // json can access var2
  };
}

arg1 = 'test';
arg2 = function() {
  window.alert('test')
};
var5 = new test(arg1, arg2);
var5.var4();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...