如何在不使用新关键字的情况下从函数创建对象

时间:2016-05-17 07:38:25

标签: javascript

我有一个功能。说函数createObj(){}

  1. var obj1 = new createObj();
  2. var obj2 = createObj();
  3. 您需要在函数createObj()中进行哪些更改,以支持带有和不带new关键字的上述场景。两者都应该同时工作。

4 个答案:

答案 0 :(得分:1)

在函数测试中this的类型,并在需要时在内部使用new关键字

function createObj()
{
   if ( !(this instanceof createObj) )
      return new createObj();

   // add existing code of function createObj here ...
}

答案 1 :(得分:0)

我可以建议您阅读一些有关JavaScript的书籍。 Object-Oriented JavaScript - Second Edition

你可以使用这个小例子:

function Sample() { // Sample is the constructor function for your objects

    return {

        prop_1: 'value',
        prop_2: 3
    }
}

var obj = Sample(); // without new

console.log(obj); // Object { prop_1="value",  prop_2=3}

var obj = new Sample(); // with new

console.log(obj); // The same result with new operator: Object { prop_1="value",  prop_2=3}
  

仅当构造函数的返回值是对象

时才可以这样做

答案 2 :(得分:0)

有点hacky并且我不建议这样做,但我理解为什么有时需要与某些遗留代码集成或转换API的原因。这是一种做法。

首先,我们需要一种方法来检测我们的函数是否使用new调用。现在,根据天气我们是否处于严格模式,如果未使用new调用,则this将为undefined或全局对象。如果用new调用它,那么它将是从原型继承的对象的实例。所以这是我们如何检查:

function createObj () {
    if (typeof this == 'undefined' || typeof this.Array == 'function') {
        // Not called with `new`
    }
    else {
        // Called with `new`
    }
}

现在使用它我们可以正确构造对象:

function createObj () {
    var self; // replacement of `this` because what it points to
              // depends on the logic below:

    if (typeof this == 'undefined' || typeof this.Array == 'function') {
        // Not called with `new`
        self = Object.create(createObj.prototype); // create object instance
    }
    else {
        // Called with `new`
        self = this;
    }

    // From this point on do things normally except use `self`
    // instead of `this`..


    // Remember to return `self` at the end for when we are not
    // called with `new`:
    return self;
}

现在该函数可以用作构造函数或对象工厂。

答案 3 :(得分:0)

删除了之前的答案,因为有一种更简单的方法

实际上有一种更简单的方法

function o(n, s) {

  function inner(n, s){
    this.name = n;
    this.surname = s;
  }

  return new inner(n, s);
}

var lee1 = new o('Bruce', 'Lee'),
    lee2 = o('Brandon', 'Lee');
console.log(lee1);
console.log(lee2);