Understanding the difference between Object.create() and new SomeFunction()

后端 未结 11 2485
失恋的感觉
失恋的感觉 2020-11-22 05:05

I recently stumbled upon the Object.create() method in JavaScript, and am trying to deduce how it is different from creating a new instance of an object with

相关标签:
11条回答
  • 2020-11-22 05:39

    Let me try to explain (more on Blog) :

    1. When you write Car constructor var Car = function(){}, this is how things are internally: A diagram of prototypal chains when creating javascript objects We have one {prototype} hidden link to Function.prototype which is not accessible and one prototype link to Car.prototype which is accessible and has an actual constructor of Car. Both Function.prototype and Car.prototype have hidden links to Object.prototype.
    2. When we want to create two equivalent objects by using the new operator and create method then we have to do it like this: Honda = new Car(); and Maruti = Object.create(Car.prototype).A diagram of prototypal chains for differing object creation methods What is happening?

      Honda = new Car(); — When you create an object like this then hidden {prototype} property is pointed to Car.prototype. So here, the {prototype} of the Honda object will always be Car.prototype — we don't have any option to change the {prototype} property of the object. What if I want to change the prototype of our newly created object?
      Maruti = Object.create(Car.prototype) — When you create an object like this you have an extra option to choose your object's {prototype} property. If you want Car.prototype as the {prototype} then pass it as a parameter in the function. If you don't want any {prototype} for your object then you can pass null like this: Maruti = Object.create(null).

    Conclusion — By using the method Object.create you have the freedom to choose your object {prototype} property. In new Car();, you don't have that freedom.

    Preferred way in OO JavaScript :

    Suppose we have two objects a and b.

    var a = new Object();
    var b = new Object();
    

    Now, suppose a has some methods which b also wants to access. For that, we require object inheritance (a should be the prototype of b only if we want access to those methods). If we check the prototypes of a and b then we will find out that they share the prototype Object.prototype.

    Object.prototype.isPrototypeOf(b); //true
    a.isPrototypeOf(b); //false (the problem comes into the picture here).
    

    Problem — we want object a as the prototype of b, but here we created object b with the prototype Object.prototype. Solution — ECMAScript 5 introduced Object.create(), to achieve such inheritance easily. If we create object b like this:

    var b = Object.create(a);
    

    then,

    a.isPrototypeOf(b);// true (problem solved, you included object a in the prototype chain of object b.)
    

    So, if you are doing object oriented scripting then Object.create() is very useful for inheritance.

    0 讨论(0)
  • 2020-11-22 05:39

    Accordingly to this answer and to this video new keyword does next things:

    1. Creates new object.

    2. Links new object to constructor function (prototype).

    3. Makes this variable point to the new object.

    4. Executes constructor function using the new object and implicit perform return this;

    5. Assigns constructor function name to new object's property constructor.

    Object.create performs only 1st and 2nd steps!!!

    0 讨论(0)
  • 2020-11-22 05:50

    Object.create(Constructor.prototype) is the part of new Constructor

    this is new Constructor implementation

    // 1. define constructor function
    
          function myConstructor(name, age) {
            this.name = name;
            this.age = age;
          }
          myConstructor.prototype.greet = function(){
            console.log(this.name, this.age)
          };
    
    // 2. new operator implementation
    
          let newOperatorWithConstructor = function(name, age) {
            const newInstance = new Object(); // empty object
            Object.setPrototypeOf(newInstance, myConstructor.prototype); // set prototype
    
            const bindedConstructor = myConstructor.bind(newInstance); // this binding
            bindedConstructor(name, age); // execute binded constructor function
    
            return newInstance; // return instance
          };
    
    // 3. produce new instance
    
          const instance = new myConstructor("jun", 28);
          const instance2 = newOperatorWithConstructor("jun", 28);
          console.log(instance);
          console.log(instance2);
          
    

    new Constructor implementation contains Object.create method

          newOperatorWithConstructor = function(name, age) {
            const newInstance = Object.create(myConstructor.prototype); // empty object, prototype chaining
    
            const bindedConstructor = myConstructor.bind(newInstance); // this binding
            bindedConstructor(name, age); // execute binded constructor function
    
            return newInstance; // return instance
          };
    
          console.log(newOperatorWithConstructor("jun", 28));
    
    0 讨论(0)
  • 2020-11-22 05:52

    This:

    var foo = new Foo();
    

    and

    var foo = Object.create(Foo.prototype);
    

    are quite similar. One important difference is that new Foo actually runs constructor code, whereas Object.create will not execute code such as

    function Foo() {
        alert("This constructor does not run with Object.create");
    }
    

    Note that if you use the two-parameter version of Object.create() then you can do much more powerful things.

    0 讨论(0)
  • 2020-11-22 05:55

    The difference is the so-called "pseudoclassical vs. prototypal inheritance". The suggestion is to use only one type in your code, not mixing the two.

    In pseudoclassical inheritance (with "new" operator), imagine that you first define a pseudo-class, and then create objects from that class. For example, define a pseudo-class "Person", and then create "Alice" and "Bob" from "Person".

    In prototypal inheritance (using Object.create), you directly create a specific person "Alice", and then create another person "Bob" using "Alice" as a prototype. There is no "class" here; all are objects.

    Internally, JavaScript uses "prototypal inheritance"; the "pseudoclassical" way is just some sugar.

    See this link for a comparison of the two ways.

    0 讨论(0)
  • 2020-11-22 05:56
    function Test(){
        this.prop1 = 'prop1';
        this.prop2 = 'prop2';
        this.func1 = function(){
            return this.prop1 + this.prop2;
        }
    };
    
    Test.prototype.protoProp1 = 'protoProp1';
    Test.prototype.protoProp2 = 'protoProp2';
    var newKeywordTest = new Test();
    var objectCreateTest = Object.create(Test.prototype);
    
    /* Object.create   */
    console.log(objectCreateTest.prop1); // undefined
    console.log(objectCreateTest.protoProp1); // protoProp1 
    console.log(objectCreateTest.__proto__.protoProp1); // protoProp1
    
    /* new    */
    console.log(newKeywordTest.prop1); // prop1
    console.log(newKeywordTest.__proto__.protoProp1); // protoProp1
    

    Summary:

    1) with new keyword there are two things to note;

    a) function is used as a constructor

    b) function.prototype object is passed to the __proto__ property ... or where __proto__ is not supported, it is the second place where the new object looks to find properties

    2) with Object.create(obj.prototype) you are constructing an object (obj.prototype) and passing it to the intended object ..with the difference that now new object's __proto__ is also pointing to obj.prototype (please ref ans by xj9 for that)

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