2

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

我将如何在同一个 Calculator Function 中组织我的代码,以便我可以同时使用 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 = [];
    }
}
4

3 回答 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}
于 2016-08-02T14:09:24.067 回答
2
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并排工作而不是反对。为了更清楚地了解原型继承和实例化,让我们退后一步,我将为您提供示例

// 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");
于 2017-02-26T02:51:39.530 回答
0

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

于 2017-01-02T02:18:54.947 回答