简体   繁体   中英

Object.create vs new

The following code works when I create my object with the constructor but when I do object.Create it doesn't get initialized properly. functionName is not a function . I have two questions. Why isn't the object.create working ?

How would I organize my code within the same Calculator Function so I could use both new and object.create ?

I know I can add the methods to Calculator.prototype and do Object.create but I was wondering if my code can be changed within the current structure to allow for both ?

//var calc = new Calculator();
var calc = Object.create(Calculator);


function Calculator(){
    this.array = [];
    this.results = 0;

    this.calculate = function(){    
        try{
        results = eval(this.array.join(''));
        this.array = [results];
        return results; 
        }
        catch(error){
            alert('Wrong arguments provided');
            return this.array.join('');
        }
    },

    this.isNumber = function(str){
        return !isNaN(parseFloat(str)) && isFinite(str);
    },

    this.addToOperationsArray = function(str){
        if (this.array.length <= 0 && !this.isNumber(str)){ // Don't add operand before any number.
            return; 
        }

        this.array.push(str);

    },
    this.clearEverything = function(){
        this.array = [];
    }
}

There is no constructor invocation with Object.create .

You can get similar results in a multitude of ways. See if something along these lines helps you:

function Calculator() {
  this.array = [];
  this.results = 0;
}
Calculator.prototype = {
  calculate: function() {
    try {
      results = eval(this.array.join(''));
      this.array = [results];
      return results;
    } catch (error) {
      alert('Wrong arguments provided');
      return this.array.join('');
    }
  },
  isNumber: function(str) {
    return !isNaN(parseFloat(str)) && isFinite(str);
  },
  addToOperationsArray: function(str) {
    if (this.array.length <= 0 && !this.isNumber(str)) { // Don't add operand before any number.
      return;
    }

    this.array.push(str);

  },
  clearEverything: function() {
    this.array = [];
  }
};

// create using 'new'
var calc1 = new Calculator();

// create using 'Object.create'
// the constructor function is not called
// but properties of returned object can be passed to the function, and
// you can control the enumerable, writable, configurable properties
var calc2 = Object.create(Calculator.prototype, {
  'array': {
    value: [],
    enumerable: true
  },
  'results': {
    value: 0,
    enumerable: true
  }
});

// create using 'Object.create'
// and invoke the constructor with 'call',
// explicitly setting 'this'
var calc3 = Object.create(Calculator.prototype);
Calculator.call(calc3);


console.log(calc1);   // Calculator {array: Array[0], results: 0}
console.log(calc2);   // Object {array: Array[0], results: 0}
console.log(calc3);   // Object {array: Array[0], results: 0}
Object.create() //This for inherit the parent object

what you want is to instantiate the object, you can do it like this:

var calc = new Calculator() //This will inherit it's prototype and execute the constructor for you.

Object.create works with new side by side not against. Just to make it more clear about prototype inheritance and instantiate, let's take step back, I'll provide you with example :

// CREATE || Object.create for inheritence by prototyping
var Thing = function (name) {
  this.type = "universal";
  this.name = name;
}

Thing.prototype = {
  say: function(something) {
    console.log(this.name + " say something " + something);
  },
  check_soul: function (){
    console.log(this.name + " soul is " + this.type);
  }
}

// constructor for God
var God = function(name){
  Thing.call(this, name); // Execute parent constructor also with current context
  this.type = "pure"; // overwrite the type
}

God.prototype = Object.create(Thing.prototype); // inherit God from Thing
God.prototype.constructor = God; // implement the constructor


// constructor for Demon
var Demon = function(name){
  Thing.call(this, name);
  this.type = "corrupted";
}

Demon.prototype = Object.create(Thing.prototype, {
  say: {
    value: function(something){ // Overwrite Thing prototype for say
    console.info(this.name + " say: Let's destory " + something + "!");
  }}
}); // inherit Demon from Thing
Demon.prototype.constructor = Demon;

/////////////////////////////////////////////////////////////////////////////////////
// NEW || new for instantiation
var anonymous = new Thing("Anonymous");
anonymous.check_soul();

var god = new God("Zeus");
god.check_soul();
god.say("omni");

var demon = new Demon("Lucifer");
demon.check_soul();
demon.say("human");

Example above is too verbose? (ES2015 here to help) note that this can only apply on node v6 and above.

// CREATE || Object.create for inheritence by prototyping

'use strict';

class Thing {
  constructor (name){
    this.type = "universal";
    this.name = name;
  }

  say(something) {
    console.log(this.name + " say something " + something);
  }

  check_soul() {
    console.log(this.name + " soul is " + this.type);
  }
}

class God extends Thing { // inherit God from Thing and implement the constructor
  constructor (name){
    super(name); // Execute parent constructor also with current context
    this.type = "pure"; // overwrite the type
  }
}

class Demon extends Thing { // inherit Demon from Thing and implement the constructor
  constructor (name){
    super(name); // Execute parent constructor also with current context
    this.type = "corrupted"; // overwrite the type
  }

  say(something) { // Overwrite Thing prototype for say
    console.info(this.name + " say: Let's destory " + something + "!");
  }
}


/////////////////////////////////////////////////////////////////////////////////////
// NEW || new for instantiation
var anonymous = new Thing("Anonymous");
anonymous.check_soul();

var god = new God("Zeus");
god.check_soul();
god.say("omni");

var demon = new Demon("Lucifer");
demon.check_soul();
demon.say("human");

可能您已经注意到了一点点,但是在您的实现中,代码Calculator.prototype.constructor中至少有一个副作用,这将指向Object.prototype.constructor而不是Calculator构造函数,您在做什么是覆盖原型链的每个属性,最佳做法是使用点表示法添加新属性Calculator.prototype.method = () => { // some code }

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