4

In 2006, Douglas Grockford wrote an article: " Prototypal Inheritance in JavaScript". This article introduces a method of inheritance that does not involve constructors in the strict sense. His starting point is to share information between objects through prototypal inheritance even without custom types. The article finally gives a function:

 function object(o) {
     function F(){}
     F.prototype = o
     return new F()
}

As a result, there is one more JavaScript in "Advanced JavaScript Programming" - prototypal inheritance

As a result, ECMAScript 5 added the Object.create() method to standardize the concept of prototypal inheritance

usage

 var obj = Object.create({name: 'johan', age: 23}) // obj 继承了属性name 和 age
var obj2 = Object.create(null) // obj2 不继承任何属性和方法
var obj3 = Object.create(Object.prototype) // 与 {} 和 new Object() 一个意思
var obj4 = Object.create({}, {
    property1: {
        value: true,
        writable: true
    }
}) // 第二个参数与 Object.defineProperties() 一致

Graphical Object.create implementation

 function create(proto) {
    function F(){}
    F.prototype = proto
    return new F()
}

Step 1: function F(){}

That is, to create a function, because the first letter is capitalized, it is regarded as a constructor. When a function F is created, the F constructor has this relationship with its prototype object:

 F.prototype === F.prototype; // 假设你把F.prototype当作一个值
F.prototype.constructor === F;

Object.create1

Step 2: F.prototype = proto

About to assign F.prototype to the incoming proto, so it breaks F.prototype = F.prototype and F.prototype.constructor = F , their relationship is

Object.create2

Step 3: return new F()

The interpretation of the third step is a bit puzzling, because it involves the operation of new. We said in the new changes the object that new will create an object and point the implicit prototype of this object ( __proto__ ) to Constructor's prototype object, and initializes the constructor, returning the value if value. We will also introduce it in subsequent prototypes (which will be introduced in subsequent articles), new is implicit prototypal inheritance, and Object.create is explicit prototypal inheritance

Here, we interpret it in terms of implementing new return new F() . new F of the instance after __proto__ points to F.prototype, and this value has been pointed to the passed proto in the second step, so there is new F().__proto__ = proto

Object.create3

Maybe you still don’t know the third step, let’s combine the examples to make it clear at a glance

 var obj = Object.create({name: 'johan'})

The diagram of the third step becomes like this:

Object.create4

This is it, obj inherits from {name: johan} this object, as for F.prototype = {name: 'johan'} , after calling Object.create , it is also used by the engine because no one uses the F function. For garbage collection, it became obj.__proto__ = {name: 'johan'}

In this way, "prototype inheritance" is passed down.

The principle is this, in simple terms, it is to create an empty (constructor) function and associate its prototype (implement inheritance)

Object.create(null)

When reading the source code, you will often see Object.create(null) , use this to initialize a new object, as for why this method is used instead of new Object or {}, because no matter new or literal, it is inherited from the Object structure function, and using Object.create(null), you can get an object without any trace of inheritance

 var obj = Object.create(null)

If you don't believe me, you can print obj and try

After talking about new and Object.create, let's take a look at the prototype (will be introduced in subsequent articles)

series of articles


山头人汉波
394 声望555 粉丝