Can I construct a JavaScript object without using the new keyword?

后端 未结 15 2595
北海茫月
北海茫月 2020-11-27 16:04

Here is what I\'d like to do:

function a() {
  // ...
}
function b() {
  //  Some magic, return a new object.
}
var c = b();

c instanceof b // -> true
c          


        
相关标签:
15条回答
  • 2020-11-27 16:50

    You can create instances without the new operator (here is a great article written about this by Douglas Crockford http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/). But it will not help you with the "instanceof" story.

    0 讨论(0)
  • 2020-11-27 16:51

    By using Object.create and the classical Function.prototype. Setting up the prototype chain properly, you preserve proper functioning of the instanceof keyword without any use of the new keyword.

    function A() {
        return Object.create(A.prototype);
    }
    
    function B() {
        return Object.create(B.prototype);
    }
    
    B.prototype = Object.create(A.prototype);
    
    var c = B();
    
    assert(c instanceof A);
    assert(c instanceof B);
    
    0 讨论(0)
  • 2020-11-27 16:53

    You can use this pattern:

    function SomeConstructor(){
       if (!(this instanceof SomeConstructor)){
            return new SomeConstructor();
       }
       //the constructor properties and methods here
    }
    

    after which you can do:

    var myObj = SomeConstructor();
    

    In addition to this (rather old) answer: you can use a module pattern to create an object:

    function Person(name, age, male) {
      name = name || 'unknown';
      age = age || 0;
      function get() {
        return ['This person is called ', name,
                (!male ? ', her' : ', his'),' age is ',
                age].join('');
      }
      function setAge(nwage) {
         age = nwage;
      }
      return Object.freeze({get: get, setAge: setAge});
    }
    // usage
    var jane =  Person('Jane', 23)
       ,charles = Person('Charles', 32, 1)
       ,mary = Person('Mary', 16);
    
    console.log(jane.get()); //=> This person is called Jane, her age is 23
    mary.setAge(17);
    console.log(mary.get()); //=> This person is called Mary, her age is 17
    

    Here's a jsFiddle for some Date functionallity I created using that pattern.

    0 讨论(0)
  • 2020-11-27 16:57

    Yes.

    function _new(classConstructor, ...args) {
      var obj = Object.create(classConstructor.prototype);
      classConstructor.call(obj, ...args);
      return obj;
    }
    
    function test_new() {
      function TestClass(name, location) {
        this._name = name;
        this._location = location;
        this.getName = function() {
          return this._name;
        }
      }
    
      TestClass.prototype.getLocation = function() {
        return this._location;
      }
      TestClass.prototype.setName = function(newName) {
        this._name = newName;
      }
    
      const a = new TestClass('anil', 'hyderabad');
      const b = _new(TestClass, 'anil', 'hyderabad');
    
      const assert = console.assert
      assert(a instanceof TestClass)
      assert(b instanceof TestClass)
      assert(a.constructor.name === 'TestClass');
      assert(b.constructor.name === 'TestClass');
      assert(a.getName() === b.getName());
      assert(a.getLocation() === b.getLocation());
      a.setName('kumar');
      b.setName('kumar');
      assert(a.getName() === b.getName());
      console.log('All is well')
    }
    test_new()

    Ref: https://gist.github.com/aniltallam/af358095bd6b36fa5d3dd773971f5fb7

    0 讨论(0)
  • 2020-11-27 16:58

    In a javascript bookmarklet, you could use eval(unescape("...")) to create object without "new" operator:

    javascript:xhr=eval(unescape('new\x20XMLHttpRequest();'));alert(xhr);
    
    0 讨论(0)
  • 2020-11-27 17:00

    What's wrong with using the new keyword?

    At any rate, it sounds like the best thing to do is read up on Javascript inheritance: http://javascript.crockford.com/inheritance.html

    0 讨论(0)
提交回复
热议问题