So, first of all, a little bit about function creation

In JavaScript, we create A Function called A(that is, declare A Function), and the JS engine creates the Function using the constructor Function. Therefore, the constructor attribute of all functions points to the constructor Function. A.constructor === Function; //true (the function itself does not have this property, described below. It then creates a prototype object in memory. The prototype object is invisible and can only be retrieved from the function’s prototype. Prototype’s property value is this object.

Again, object creation

There are three ways to create an object.

What is a literal? Anything that doesn’t come out of new is a literal creation.

Here’s an example:

var c = {}; //c is a variable, {} is a literalCopy the code

The creation of a literal Object is similar to the creation of a function. When you declare an Object literal, the JS engine creates the Object, so the effect is the samenew Object()

2. Constructor mode

And this one, it’s created with new.

Chestnuts are here:

var c = new Object();
Copy the code

3, the Object. The create

This is a new method in ES5, which creates a new object and points its __proto__ to the function or object passed in. What’s going on? Now, let’s simply implement its function, okay

Function create(proto, options){//proto represents the function or object passed in, options represents the attribute added to the subclass var obj = {}; obj.__proto__ = proto; if(options == null){ return obj; } return Object.defineProperties(obj,options); / / Object. DefineProperties method directly on an Object to define new attributes, or modify an existing attribute, and returns the Object. So I'm just going to return}Copy the code

Check it out:

var a = function(){}; Var b = create(a); console.log(b.__proto__ === a); //true; var c = create(a.prototype); console.log(c.__proto__ === a.prototype); //true //Object.create var d = create(a); console.log(d.__proto__ === a); //true; var e = create(a.prototype); console.log(e.__proto__ === a.prototype); //trueCopy the code

To illustrate, the create implementation you can see elsewhere looks like this:

// This simplifies the second argument. Function create(proto){function f(){}; f.prototype = proto; return new f(); }Copy the code

This is compatible because the __proto__ attribute is non-standard, and some browsers now implement it. In fact, if you understand what New does, you can see that these two are actually the same thing.

  1. Create a new object (instance object)
  2. Put the new object__proto__Point to thenewThe prototype object for the following constructor.
  3. The constructorthisPoints to an instance object.
  4. Do some processing and return the instance object.

Here, write a method to implement the new function:

Function New(func){//func refers to the constructor passed in, which is used to generate an instance of an object. var obj = {}; // Create an empty Object instead of a new Object. The effect is the same, because I feel it is not good to use the new function. if(func.prototype ! = null){ obj.__proto__ = func.prototype; } func.apply(obj,Array.prototype.slice.call(arguments, 1)); // Place this in the func constructor to the obj object, starting with the second argument passed in, and execute it in the func constructor, such as attribute assignment. return obj; }Copy the code

I do not know if you see it, simply point out

function create(proto){ var f = function(){}; f.prototype = proto; return new f(); Function create(proto){var f = function(){}; var obj = {}; f.prototype = proto; obj.__proto__ = f.prototype; return obj; Function create(proto){var obj = {}; obj.__proto__ = proto; return obj; } // Function f is used as a transition. Function a(){}; var b = create(a); console.log(b.__proto__ === a); //true;Copy the code

The prototype chain begins!

I think it’s frustrating to talk about JavaScript prototypes, where the connection between prototype and __proto__ is too much of a headache, but it’s easier to look at pictures than words. Most of the tutorials I read are aboutprototype__proto__Put together, I think it would be better to separate, is not a thing


Prototype attribute

This is a function property that holds a reference to its prototype object, that is, to the prototype object. (Any function has a prototype object.) Its prototype object is invisible, can’t touch, only through the functionprototypeProperty to retrieve it.

Such as

function A(){}; A.prototype; // Get the prototype object of ACopy the code

Summary: You seeprototypeYou just think of it as corresponding to its prototype object.





Second, prototype object

Whenever you create a function, JS generates a corresponding prototype object. It can only be a functionprototypeProperty is obtained. (A.prototypeThe overall realization is zeroAThe prototype object of


There are only two types of objects: instance objects (objects created by new and literals) and prototype objects.


_ _ proto _ _ attribute

This is a non-standard property that some modern browsers support, such as Firefox and Google. The corresponding standard attribute is [[prototype]], which is a hidden attribute and cannot be retrieved. This property is what links all the functions, all the objects, into a chain, which we call a prototype chain. The end of this chain is Object.prototype.__proto__ === null.

So who does it point to? I’ll give you two ways to remember it:

Function __proto__ refers to function. protoype, and prototype __proto__ refers to Object.prototype. Object. Create specifies the Object to which you give it the name of the prototype. 2. __proto__ refers to the prototype Object’s constructor, except that __proto__ refers to object. prototype. (If you understand the implementation of New above, you should understand why.)

Second note: all functions are constructorsFunctionSo, the constructor of the function isFunction.

Choose which of these two you like and look at the picture below for the answer:


4. Constructor attribute

constructorProperties are unique to the prototype object and refer to its constructor. The aboveA prototype,Delta delta delta delta delta delta delta delta delta deltaprototypeProperty points to its prototype object. The function is now a constructor.So the function and its prototype object remain related by these two properties. Such as:

function A(){};
A.prototype.constructor === A   //true

Object.prototype.constructor === Object   //true
Copy the code

What about function constructor and normal object constructor?

Function A(){}; A. Constructor is there any confusion? Isn’t that just for prototype objects?

If A does not have the constructor property on it, it will find the constructor property up the constructor chain. If A does not have the constructor property on Object, it will find the constructor property.

Such as:

var Person = function(name) { this.name = name; } Person.prototype.getName = function(){ return this.name; } var p = new Person("666"); console.log(p.getName()); / / 666Copy the code

There is no getName method in the Person constructor, but how can p instance be used? Because of p instance__proto__The prototype object pointed to has a getName function, so P looks up the prototype object of Person on the prototype chain, and it has a getName method, so P can use this method.

Note: So, when looking for a constructor, be careful to look on its prototype chain, not on the prototype object:

Object.constructor === Object.__proto__.constructor
//true
Copy the code


Constructors

What is a constructor? In fact, every function is a constructor, but we usually call the function that generates the instance object a constructor (via new, the constructor after new), which is essentially a function.

Such as:

var Person = function(name) { this.name = name; this.getName = function(){ return this.name; } } var p1 = new Person("zdx"); console.log(p1.getName()); //zdx var p2 = new Person("666"); The console. The log (p2) getName ()) / / 666 console. The log (Person) prototype) constructor = = = Person) / / / true / / the Person here is a function right, And then outside I'm going to call new Person(); // Create an instance of Person. At this point, Person is a constructor, or class, and we capitalize the first letter of the class. // Because this function can construct an infinite number of instances using new.Copy the code

For those of you who don’t know, an instance is an instance object, because an instance is itself an object.


6. Prototype chain

Start magnifying, ha ha:

function Person(name) { this.name = name; } var p = new Person("zdx"); console.log(p.__proto__ === Person.prototype); //true //p is the instance object, its constructor is Person, as mentioned above, it is new, Prototype console.log(person.prototype. __proto__ === object.prototype); Prototype.console. log(person.__proto__ === function.prototype); //true //Person. //true //Person is a constructor whose constructor is Function, Prototype console.log(function.prototype. __proto__ === object.prototype); Prototype. console.log(object.prototype. __proto__ === null); //true //Function. //true // This is the end of all prototype chains.Copy the code

So js everything is an object? All functions, objects, instances, and its prototype chain end up in the Object. Prototype Object.

Drawn as a sauce drops: In fact, sometimes looking at pictures is not the same. Ha ha, you can follow the rules I said and look at the pictures yourself.

So let’s just check that out

var a = {}; // Equivalent to new Object() console.log(a.prototype); //undefined has no console.log(a.__proto__ === object.prototype); //true var b = function(){}; console.log(b.prototype); //b's prototype pair looks like console.log(b.__proto__ === function.prototype); var c = []; Arrayconsole.log (c.__proto__ === array.prototype); //true var d = ""; // Equivalent to new String(), the constructor is String console.log(d.__proto__ === string.prototype); //trueCopy the code


The role of prototype chain

In fact, the basic function of the prototype chain is to read attributes. To put it more broadly, it is code encapsulation reuse, inheritance.

As mentioned briefly, when reading a property from a function or object, it looks for its own property first, returns it if it has one, and looks up the prototype chain if it doesn’t.

For a simple example, every function, every object, has a toString method. Where does it come from? Sacks! (Wait), it’s not a property read. ToString is a method. Classmate, you have a good eye. In fact, we call properties with values of functions methods. In fact, you need to understand how these methods work.

function test(){}; test.toString(); //"function test(){}" console.log(test.hasOwnProperty("toString")); //false console.log(test.__proto__.hasOwnProperty("toString")); //true // The hasOwnProperty method checks if the property is its own property // and (__proto__) test.__proto__ points to (equal to) function.prototype console.log(test.__proto__ === Function.prototype); //true console.log(Function.prototype.hasOwnProperty("toString")); //true // See here, see? The built-in methods (functions) part of the Function are properties on function.prototype; // Part of it? Yes, because the end of the prototype chain is Object.prototype; // So the properties, methods, and functions added to object. prototype are available; Prototype. Say = function() {console.log(5666)}; function test(){}; test.say(); / / 5666Copy the code

So what about attribute assignment?

First the function or object looks for its own property, if it has it overwrites the value of that property, if it doesn’t it creates a property of its own, anyway, assignment doesn’t look up the prototype chain.

function Person(){}; var p = new Person(); // If you run this in the same window, the result may be 5666 above, since you just changed the function, you can reopen a browser window. p.toString(); //"[object object]" // toString = Function. Prototype; Function. The prototype. ToString = Function () {the console. The log (" I am the Function prototype object "); } Person.toString(); // I'm Function prototype object p.tostring (); //"[object object]" // The toString method on object has not changed.Copy the code


The application of prototype chain in actual code

The most common use is inheritance.

Function Person(name){// this. Name = name; } person.prototype.getName = function(){return this.name; } function Son(name,age){// Subclass (constructor) this.name = name; Person.call(this, name); person.call (this, name); this.age = age; } Son.prototype = new Person(); // Attach the prototype object of the subclass (constructor) to the prototype chain. Son.prototype.getAge = function(){ return this.age; } var s = new Son("zdx",666); s.getName(); //Son. Prototype does not have a getName method.Copy the code

Do I need to read that?

Son.prototype = new Person(); Var obj = {}; obj.__proto__ = Person.prototype; Son.prototype = obj; // Attach Son. Prototype to the prototype chain. Son.prototype.__proto__ === Person.prototype //tureCopy the code

Then when the method is used on Son’s instance object, it looks up the chain. Son. Prototype doesn’t have it, but the parent Person. Ok, inherited.


Interpret the prototype chain of JQ

Write a simple one:

var jQuery = function(name) {
    return new jQuery.fn.init();
}

jQuery.fn = jQuery.prototype = {
    constructor: jQuery,
    init: function(name) {
        this.name = name;
    },
    each: function() {
        console.log('each');
        return this;
    }
}

jQuery.fn.init.prototype = jQuery.fn;

Copy the code

It might seem a little bit difficult, but that’s okay. Let’s simplify

function jQuery(name){
	return new init(name);
}

function init(name){
	this.name = name;
}

jQuery.prototype = {
    constructor: jQuery,
	each: function(){ 
	    console.log('each')
	}
}

init.prototype = jQuery.prototype;

Copy the code

If you use jQuery(), it’s the same as new jQuery(); New init() and new jQuery(); It’s the same; Because init.prototype = jquery. prototype, the instance object is the same. It is written so that it is easy for you to use and does not require you to use new to create jQ objects.

This is how it works:

The $(); New $(); // Much more convenient.Copy the code

Finally, don’t confuse prototype chains with scope chains!! Ha, ha, ha