New understanding constructor, prototype and prototype chain

This article focuses on the constructor, prototype and prototype chain-related knowledge, if you do not know  is not a constructor,  property is read-only  ,  and  the difference between what is the prototype chain, we recommend that you take to read this article, I hope you have the help. Symbolconstructorprototype[[Prototype]] __proto__

 

 

Constructor

What is the constructor

constructor The constructor returns a reference when creating an instance of an object. The value of this attribute is a reference to the function itself, instead of a string containing the name of the function.

function Parent(age) {
    this.age = age;
}

var p = new Parent(50);
p.constructor === Parent; // true
p.constructor === Object; // false

The constructor itself is a function, there is no difference between an ordinary function, but in order to regulate general to capitalize the first letter. Constructor function and the difference is that ordinary, using  generation function is an example of a constructor, a direct call is an ordinary function. new

Does that mean no ordinary function to create an instance of  attribute it? Not necessarily. constructor

// 普通函数
function parent2(age) {
    this.age = age;
}
var p2 = parent2(50);
// undefined

// 普通函数
function parent3(age) {
    return {
        age: age
    }
}
var p3 = parent3(50);
p3.constructor === Object; // true

Symbol is the constructor it

MDN is introduction  of Symbol

The Symbol() function returns a value of type symbol, has static properties that expose several members of built-in objects, has static methods that expose the global symbol registry, and resembles a built-in object class but is incomplete as a constructor because it does not support the syntax "new Symbol()".

Symbol Is the basic data types, but as a constructor for it is not complete because it does not support the syntax , Chrome believe it is not a constructor, if you want to create instances directly  to. (From MDN) new Symbol() Symbol()

new Symbol(123); // Symbol is not a constructor 

Symbol(123); // Symbol(123)

Although the basic data types, but   Symbol(123) instances can obtain  an attribute value. constructor

var sym = Symbol(123); 
console.log( sym );
// Symbol(123)

console.log( sym.constructor );
// ƒ Symbol() { [native code] }

Here's   constructor where the properties come from? In fact  the prototype, that  return creates an instance of the prototype of the function, the default is  function. SymbolSymbol.prototype.constructor Symbol

constructor value read-only

The scores, for reference types for the  attribute value can be modified, but the basic type is read-only. constructor

Reference types whose values can change this situation is well understood, such as the prototype chain of inheritance scheme, we need to re-assign correct. constructor

function Foo() {
    this.value = 42;
}
Foo.prototype = {
    method: function() {}
};

function Bar() {}

// 设置 Bar 的 prototype 属性为 Foo 的实例对象
Bar.prototype = new Foo();
Bar.prototype.foo = 'Hello World';

Bar.prototype.constructor === Object;
// true

// 修正 Bar.prototype.constructor 为 Bar 本身
Bar.prototype.constructor = Bar;

var test = new Bar() // 创建 Bar 的一个新实例
console.log(test);

 

 

 

For the basic type is read-only, such as , of course,  and there is no  attribute. 1、“muyiy”、true、Symbol null undefined constructor

function Type() { };
var    types = [1, "muyiy", true, Symbol(123)];

for(var i = 0; i < types.length; i++) {
    types[i].constructor = Type;
    types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ];
};

console.log( types.join("\n") );
// function Number() { [native code] }, false, 1
// function String() { [native code] }, false, muyiy
// function Boolean() { [native code] }, false, true
// function Symbol() { [native code] }, false, Symbol(123)

why? Because they create a read-only native Constructor ( native constructors), this example also illustrates the dependence of an object  property is not safe. constructor

Analog achieve new

Here we must talk about  implementation, and codes are as follows. new

function create() {
    // 1、创建一个空的对象
    var obj = new Object(),
    // 2、获得构造函数,同时删除 arguments 中第一个参数
    Con = [].shift.call(arguments);
    // 3、链接到原型,obj 可以访问构造函数原型中的属性
    Object.setPrototypeOf(obj, Con.prototype);
    // 4、绑定 this 实现继承,obj 可以访问到构造函数中的属性
    var ret = Con.apply(obj, arguments);
    // 5、优先返回构造函数返回的对象
    return ret instanceof Object ? ret : obj;
};

prototype

prototype

JavaScript It is a prototype-based language  (prototype-based language), and the  other class-based language is not the same. Java

Each object has a prototype object , the object as a template for its prototype, prototype inheritance from the definition of methods and properties, these properties and methods in the constructor function of the object  on the property, not the object instance itself. prototype

 

 

From the above can be found in this figure, Parent the object has a prototype object , which has two attributes, respectively  , and in which  is deprecated. Parent.prototype constructor __proto__ __proto__

Constructors  have a pointer pointing to the prototype, the prototype  has a pointer to a constructor , as shown above, in fact, is a circular reference. Parent Parent.prototype Parent.prototype.constructor

 

 

__proto__

Parent prototype can be seen on FIG. (  ) Have the  property, which is an access properties (i.e., functions and setter getter function), access to the interior of the object through which the  (or an object    ). Parent.prototype __proto__ [[Prototype]]null

__proto__ Pronunciation dunder prototype, the first to be using Firefox, and later as standard Javascript's built-in property ES6.

[[Prototype]] Is an internal property of an object, external code can not be directly accessed.

Follow standard ECMAScript, someObject. [[Prototype]] for symbol point someObject prototype.

 

 

Used here  get the object prototype,  it is in each instance have the property  is a property of the constructor, the two are not the same, however    , and  the same object. p.__proto____proto__prototypep.__proto__ Parent.prototype

function Parent() {}
var p = new Parent();
p.__proto__ === Parent.prototype
// true

Therefore, the constructor   Parent, Parent.prototype and  the following relationship in FIG. p

 

 

important point

__proto__ Property  only to be standardized to ensure compatibility with Web browsers, but not recommended, in addition to the standardization of the reasons there are performance issues. To better support, it is recommended . ES6 Object.getPrototypeOf()

By changing an object  to change the properties and inherited attributes will cause very serious impact on performance, and the performance of the time spent is not a simple cost in  the statement, it will affect all inherited from the  object, if you care about performance you should not modify an object . [[Prototype]] obj.__proto__ = ...[[Prototype]] [[Prototype]]

To read or modify the object  attributes, the following protocol is recommended, but this time the set of objects  is still a slow operation, if the performance is a problem, it is necessary to avoid this operation. [[Prototype]][[Prototype]]

// 获取
Object.getPrototypeOf()
Reflect.getPrototypeOf()

// 修改
Object.setPrototypeOf()
Reflect.setPrototypeOf()

If you want to create a new object that inherits another object   [[Prototype]] it is recommended Object.create().

function Parent() {
    age: 50
};
var p = new Parent();
var child = Object.create(p);

Here  is a new empty object, there is a pointer to the object p . child __proto__

Optimized for new

As described above, it is not recommended , so we use  to simulate achieve, optimized code as follows. __proto__ Object.create()

function create() {
    // 1、获得构造函数,同时删除 arguments 中第一个参数
    Con = [].shift.call(arguments);
    // 2、创建一个空的对象并链接到原型,obj 可以访问构造函数原型中的属性
    var obj = Object.create(Con.prototype);
    // 3、绑定 this 实现继承,obj 可以访问到构造函数中的属性
    var ret = Con.apply(obj, arguments);
    // 4、优先返回构造函数返回的对象
    return ret instanceof Object ? ret : obj;
};

Prototype chain

Each object has a prototype object,  a pointer to a prototype, and inherited methods and properties from, but may also have a prototype prototype object, such layer by layer, the final point . This relationship is called prototype chains (catena alberghiera the prototype) , by a chain of prototype objects have properties and methods defined in other objects. __proto__ null

Here we see an example

function Parent(age) {
    this.age = age;
}

var p = new Parent(50);
p.constructor === Parent; // true

Here  point , it is not meant to  exist instance attributes? It is not. parent.constructor Parent parent constructor

We print the next  value to know. parent

 

 

Can be seen from FIG instance object  does not have  properties, it is to look up through the prototype chain , to find the final  attribute points . p constructor __proto__ constructor Parent

function Parent(age) {
    this.age = age;
}
var p = new Parent(50);

p;    // Parent {age: 50}
p.__proto__ === Parent.prototype; // true
p.__proto__.__proto__ === Object.prototype; // true
p.__proto__.__proto__.__proto__ === null; // true

The following figure shows the operating mechanism of the prototype chain.

 

 

summary

  • Symbol As a constructor, it is not complete, because they do not support the syntax , but with its prototype  property, that is . new Symbol()constructor Symbol.prototype.constructor

  • Reference type  attribute value can be modified, but the basic type is read-only, of course,  and  no  property. constructornull undefined constructor

  • __proto__ There is on each instance attribute prototype is an attribute of the constructor, the two are not the same, however   p.__proto__ , and  the same object. Parent.prototype

  • __proto__ Property  when it is standardized, but is not recommended because of performance problems, it is recommended to use . ES6Object.getPrototypeOf()

  • Each object has a prototype object,  a pointer to a prototype, and inherited methods and properties from, but may also have a prototype prototype object, such layer by layer, the final point , which is the prototype chain. proto null

Guess you like

Origin www.cnblogs.com/duanlibo/p/11642222.html