简体   繁体   中英

JavaScript constructors using JavaScript object literal notation

What is the best way to build constructors in JavaScript using object literal notation?

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

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

I want to be able to call

var myVar = new myObject(...);

And pass the arguments to a constructor function inside myObject.

This is not "JSON notation", this is JavaScript object literal notation . JSON is only a subset of JS object literal notation, but apart from looking similar, they have nothing in common. JSON is used as data exchange format, like XML.

It is not possible what you want to do.

var myObject = {};

creates already an object. There is nothing what you can instantiate.

You can however create a constructor function and add the methods to its prototype:

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`
 }
};

Every object you instantiate with new MyObject() will inherit the properties of the prototype (actually, the instances just get a reference to the prototype object).

More about JavaScript objects and inheritance:


Update2:

If you have to instantiate many objects of the same kind, then use a constructor function + prototype. If you only need one object (like a singleton) then there is no need to use a constructor function (most of the time). You can directly use object literal notation to create that object.

Make the object a function, like this:

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'});

Sorry for being late to the party, but... I think saying that this is not possible is a little restrictive depending on how you interpret the OP's question and subsequent comments.

Assuming the OP wanted the namespacing benefits that object literal notation can bring to a library but also wanted to have some "classes" to use within that structure. Could you not use something of this form to combine constructor patterns in to an object literal notation namespaced library structure?

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

They're silly examples, but is there any reason not to do this, or why this isn't valid? It gets rid of the global crowding problem that people usually want to use object literal notation for with libraries.

var myObject = function(arg){
    return{
        constructor: function(arg){
            //...
            return this;
        },

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

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

//...

var myVar = new myObject("...");
var myObject = {
 funca : function() {
  //...
 },

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

you can not create a new object of above this way

var myVar = new myObject(...);

but you can achieve the same with below construct,

var myVar = Object.create(myObject );

The simplest way I know is:

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();

Well, calling new on the object literal is not possible, as others already answered.

But calling new on the object literal constructor is possible.

 var obj = { arg1: null, arg2: null }; var obj1 = new obj.constructor(); var obj2 = new obj.constructor(); obj1.arg1 = 1; obj2.arg1 = 2; console.log("obj2.arg1:", obj2.arg1); console.log("obj1.arg1:", obj1.arg1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM