简体   繁体   中英

Object.create works new() doesn't

Having this:

sillyObject = {
    init: function init(sillySettings) {
        name = sillySettings.name
    }
};

sillyObject.showAlert = function(x) {
    return alert(x);
};

When I run this code:

var sillyvar  = new sillyObject()
sillyvar.init(mySettings);
silly.showAlert("silly!");

I get an error but instead if I run the same thing using Object.create it runs..

var sillyvar  = Object.create(sillyObject);
sillyvar.init(mySettings);
silly.showAlert("silly!");

Any (silly) help will be appreciated.

If you tried doing new sillyObject() , the error you get is Uncaught TypeError: object is not a function since sillyObject is an object and not a function.

This answer gives a good overview on the new keyword.

Object.create does not do the same thing as new . It will create a new object with sillyObject as the prototype.

new and Object.create are two fundamentally different things.

new is going to expect to be followed by a function, and if not (as you saw) it will give you an error. That is because new expects to call a constructor function and then use that as a basis for a new execution context. During that context, the function has this bound to the scope of the execution context. Once the function is done executing it returns the this value which usually has had some data attached to it. In your example, that would look like this:

function sillyObject() {}
sillyObject.prototype.init = function(sillySettings) {
   //perhaps you wanted to attach this name to the sillyObject?
   name = sillySettings.name;
   //which would look like this
   this.name = sillySettings.name;
   //because `this` here refers to the object context (remember?)
};
sillyObject.prototype.showAlert = function(x){
   return alert(x);//returning alert simply returns undefined (not sure why this is used here)
};

and then you could use new, it would create the execution context using the constructor and then attach the prototype and you would end up with a new instance of sillyObject (all instances would be different).

var sO = new sillyObject();
sO.init(mySettings);
sO.showAlert("silly!");

Object.create() on the other hand is expecting an object as an argument (which is why your version worked here). It will create a new object using that object argument as a template basically. Or as MDN explains it "The Object.create() method creates a new object with the specified prototype object and properties". This basically creates a copy if nothing else is done with the Object, and that is why the alert worked here but not in the new version.

sillyObject is a Object not a function. new will create a new instance of a function. You probably want to use this or just .prototype

var sillyObject = function () {
    this.sillySettings = {};
}

sillyObject.prototype = {
    init     : function (name) {
        this.sillySettings.name = name;
    },

    showAlert: function (x) { 
       return alert(x);
    }
};

var silly = new sillyObject(); 
silly.init('foo');
silly.showAlert('bar');

this.sillySettings isn't a function so we don't keep it in the prototype. We can keep init and showAlert in the prototype. We use prototype because when using new we use sillyObject() so imagine the variable silly being replaced this sillyObject() showing why we use prototype because silly is instantiated as a function.

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