首页 文章

Object.create vs new

提问于
浏览
2

当我使用构造函数创建我的对象时,下面的代码工作,但是当我做object.Create它没有正确初始化 . functionName is not a function . 我有两个问题 . 为什么object.create不起作用?

我如何在同一个计算器函数中组织我的代码,以便我可以同时使用new和object.create?

我知道我可以将方法添加到Calculator.prototype并执行Object.create,但我想知道我的代码是否可以在当前结构中更改以允许两者兼而有之?

//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 = [];
    }
}

3 回答

  • 3

    没有Object.create的构造函数调用 .

    您可以通过多种方式获得类似的结果 . 看看这些内容是否有助于您:

    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}
    
  • 0
    Object.create() //This for inherit the parent object
    

    你想要的是实例化对象,你可以这样做:

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

    Object.createnew 一起使用并不反对 . 只是为了使它成为 more clear 关于原型继承和实例化,让's take step back, I' ll为你提供 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");
    

    上面的例子太冗长了吗? (ES2015在这里提供帮助)请注意,这只适用于节点v6及更高版本 .

    // 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");
    
  • 2

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

相关问题