[toc]

A prototype.

1. Function prototype properties (figure)

** Each function has a prototype property, which by default points to an empty Object (called: prototype Object)*

The ** prototype object has a property constructor that points to the function object *

2. Add attributes to the prototype object (usually methods)

All instance objects of a function automatically have properties (methods) in the stereotype *

<script type="text/javascript"> // Each function has a prototype attribute, which by default points to an empty Object. Console. log(date.prototype, Typeof date.prototype) function Fun() {} console.log(fun.prototype) // Defaults to an Object empty Object (without our properties) // // The stereotype object has a property constructor, . It refers to the function object the console log (Date) prototype) constructor = = = the Date) the console. The log (Fun) prototype) constructor = = = Fun) / / Function () {console.log('test()')} var Fun = new Fun() fun.test() </script>Copy the code

1.1 Prototype and _ _ proto _ _

In JavaScript, every function has a prototype property that points to the function’s prototype object.

1. Every function has a prototype

2. Each instance object has one__proto__, can be called implicit archetype (attribute)

3. The implicit stereotype of an object is the explicit stereotype of its corresponding constructor

// 3. The implicit prototype of the object is the explicit prototype of its corresponding constructor console.log(fn.prototype === fn.__proto__) // trueCopy the code

1.2 Understand the memory diagram of the prototype

<! Each function has a prototype. Each instance object has a __proto__, which can be called an implicit prototype (attribute) 3. The implicit stereotype of an object is the explicit stereotype of its corresponding constructor. The prototype property is automatically added when the function is defined. The default value is an empty Object * the __proto__ property of the Object: The default value is the constructor's prototype property * Programmers can directly operate on explicit prototypes, but not on implicit prototypes (pre-ES6) --> <script type="text/javascript"> // one. Function Fn() {this.prototype = {}} // 1. Each function has an explicit prototype property that by default points to an empty Object console.log(fn.prototype) // 2. Each instance object has a __proto__, which can be called an implicit prototype // two. Prototype console.log(fn.__proto__) // 3. The value of the implicit prototype of the object is the value of the explicit prototype of its corresponding constructor console.log(fn.prototype === fn.__proto__) // true // three. Test = function () {console.log('test()')} Fn.test () //test() </script>Copy the code

1.3 Basic use of prototypes

When we write code using prototypes, we usually do this:

==1. Write attributes inside the constructor. = =

==2. Write methods on the prototype object. = =

This avoids the problem of wasting memory

1.4 Trigonometric relation between constructor and instance object and prototype object

  /* Prototype: 1. Is an attribute of the constructor, is an object, is automatically assigned when we create the constructor to provide the constructor instance object with method 2. Prototype - provides methods for instance objects. 2. Constructor. Prototype and instance object.__proto__ 3. The prorotype attribute is the constructor, and the __proto__ attribute is the instance object */
    function Person(name, age, gender) {
      this.name = name
      this.age = age
      this.gender = gender
    }

    Person.prototype.sayHi = function () {
      console.log('sayHi was called ');
    }
    // console.dir(Person)
    console.log(Person.prototype);
    // 2. Prove that the prototype's constructor property is the constructor
    console.log(Person.prototype.constructor === Person); //true

    let p1 = new Person()
    let p2 = new Person()

    // p1.sayHi()
    // p2.sayHi()
    // console.log(p1);
    // console.log(p2);

    //1. Prove that __proto__ is the prototype of the constructor
    // console.log(p1.__proto__ === p2.__proto__); //true
    // console.log(p1.__proto__ === Person.prototype); //true
    // console.log(p2.__proto__ === Person.prototype); //true
Copy the code

A prototype is essentially an object that is automatically allocated in the browser whenever a constructor is created.

The purpose of this object is to implement object sharing methods.

We can access this object in two ways:

1.Access a prototype from a constructor: constructor. Prototype2.Accessing prototypes from instance objects: instance objects.__proto__Copy the code

1.5 Prototype Summary

  1. A prototype is simply an object that exists in memory and is invisible to us
  2. A stereotype can provide methods to an instance object of a constructor
  3. Constructor. PrototypeInstance object __proto__All have access to the prototype object
  4. There areprototypeProperty is the constructor, there are__proto__Property is the instance object
  5. Function prototype property: added automatically when a function is defined. The default value is an empty Object
  6. The object’s__proto__Property: Automatically added when the object is created, default to the constructor’s Prototype property value
  7. Programmers can directly manipulate explicit stereotypes, but not implicit stereotypes (prior to ES6)

1.6 Principles of prototyping

A stereotype is better than a constructor alone because it is unique in memory, and therefore in methods.

At this time no matter how many instances we new objects, they will be at the time of call methods, along its __proto__ find a prototype object attributes, and then call the prototype object corresponding method, because there will be only a prototype object, so the method corresponding to the function object is there will be only one, it solved the problem of the waste of memory.

In memory, such an association already exists before multiple objects

Package a simple jQuery

JQuery uses prototypes to achieve a lot of code encapsulation, so we use the knowledge of prototypes, imitate jQuery code encapsulation. (This is a complicated process, so we can skip it and talk about it later in class.)

/* Simple jQuery includes: 1. Get element $(selector) 2. On (event type, handler) jquery.prototype. on = function()}*// / object oriented, in order to distinguish objects, write constructor function jQuery selector () {/ / get a pseudo array var dom = document. QuerySelectorAll (selector); Var I = 0; var I = 0; i < dom.length; i++) { this[i] = dom[i]; } this.length = dom.length; Function (prop, value) {function (prop, value) {function (prop, value); If (arguments.length === 2) {// This is an instance of the array. // This is an instance of the array. // This is an instance of the array. // For (var I = 0; i < this.length; i++) { this[i].style[prop] = value; }} else if (arguments.length === 1) {for (var key in prop) {for (var I = 0; i < this.length; i++) { this[i].style[key] = prop[key]; }}} // To support chained programming, return a jq object return this; }// if (function (type) {// if (type) {// if (type) {// if (type) {// if (type) {// if (type) {// if (type) { AddEventListener (event type, handler) for (var I = 0; i < this.length; i++) { if (typeof this[i].addEventListener === 'function') { this[i].addEventListener(type, fn); } else {// Ie register event method attachEvent this[I]. AttachEvent ('on' + type, fn); Function $(selector) {return new jQuery(selector); }
Copy the code

Prototype chain

3.1 What is a prototype chain?

In JavaScript, every object has an internal link to its prototype object. The prototype object, in turn, has its own prototype until an object’s prototype is null (that is, there is no longer any prototype to point to), forming the last link in the chain. == This chain structure is called the prototype chain.

In fact, in memory, there are multiple prototype objects, before which there is a chain relationship, which we call: prototype chain

A prototype chain is an object structure designed by javascript specifically to implement object-oriented inheritance, which can solve the problem of code reuse.

When we expand the output of the constructor’s prototype, we find that the prototype object also has a __proto__ attribute, which means that the prototype object is also an instance object

function Person(name,age,gender){}console.log(Person.prototype)
Copy the code

The __proto__ property of the prototype object is found to be an object, and there is at least one such chain in memory

We call such structural relations a prototype chain

3.2 Role of prototype chain

As we mentioned above, the == prototype chain is designed by javascript specifically to implement inheritance. Let’s leave inheritance behind and see how it works.

As we have seen, the prototype object is used to provide methods for instance objects, that is, methods above __proto__ can be used by objects. Similarly, can methods on the object now pointed to by the __proto__ attribute above the prototype object (object.__proto__) be used by the prototype object? Of course!

Let’s look at what’s the method on the prototype of this prototype

console.log(Person.prototype.__proto__)
Copy the code

You can see that there is a toString method on the prototype, so let’s try calling it

console.log(Person.prototype.toString()); // Result is: [object object]
Copy the code

You can see that methods on the __proto__ attribute are indeed available to objects.

So here’s a question: Can an instance of a function constructed by Person call the toString() method? After all the Person instance __proto__ attribute is the Person. The prototype, the Person. The prototype __proto__ attribute of the method is also quite so Person. The prototype of the method, then the instance objects access its __proto__ method, I think so

let p = new Person()console.log(p.toString()); // Result: [object object]
Copy the code

As you can see, the toString method is indeed reused through a __proto__ relationship between multiple objects.

Summary: On the prototype, methods of upstream objects can be called directly by downstream objects

3.3 Prototype chain structure

Combining the previously obtained relationship between Perosn and its prototype, we can get a more complete diagram

So we can think about a question: Does the Object prototype still have a __proto__ attribute on it?

console.log(Object.prototype.__proto__) // null
Copy the code

That is to say, the link of the prototype chain is connected to the Object prototype, and there is no link above ————. The link of the prototype chain ends in null

It’s worth noting that this set of things is not discovered by us, but a special structure designed by JS authors specifically to enable code reuse. We are just leading you to learn by derivation

In fact, the prototype chain is the basic principle that we implement inheritance in JS

Summary:

  1. The prototype chain is there, it’s deliberately designed
  2. A prototype chain is a link between objects__proto__The relationship to which the property is associated
  3. Methods by which objects at the end of the prototype chain can access objects upstream

3.4 Prototype chain member access rules

Object members == object properties + object methods

The way that objects at the end of the prototype chain can access objects upstream has certain access rules. Like scopes, members on the prototype chain follow the “proximity rule”

  • When reading a property value of an object:
  1. When accessing a member of an object, if the object has its own corresponding member, use its own member first
  2. When it has no corresponding member, it searches along the prototype chain to find the nearest one
  3. If Object. Prototype does not exist until then, return undefined
  • When setting the value of an object’s property: == Does not look up the prototype chain. If the property is not currently in the object, add it and set its value ==

  • == methods are typically defined in stereotypes, and properties are typically defined on the object itself via constructors ==

    <! -- 1. When reading the property value of the object: it will automatically look up the prototype chain 2. When setting the property value of the object: the prototype chain is not searched. If the property does not exist in the current object, the property is directly added and its value is set 3. <script type="text/javascript">  function Fn() { } Fn.prototype.a = 'xxx' var fn1 = new Fn() console.log(fn1.a, Var fn2 = new Fn() fn2.a = 'yyy' console.log(fn1.a, fn2.a, fn2) // XXX Fn{a:'yyy'} // Example 2:  function Person(name, age) { this.name = name this.age = age } Person.prototype.setName = function (name) { this.name = name } var p1 = new Person('Tom', 12) p1.setName('Bob') console.log(p1) //{'Bob',12} var p2 = new Person('Jack', 12) p2.setName('Cat') console.log(p2) //{'Cat',12} console.log(p1.__proto__ === p2.__proto__) // trueCopy the code

3.5 Prototype Chain case study (== Constructor/prototype/instance object relationship (diagram)==)

<! When accessing a property of an object, * first search its property and return * if not, then search up the __proto__ chain and return * If not, return undefined *. Find object properties (methods) 2. <script type="text/javascript"> // console.log(Object) //console.log(Object.prototype) //console.log(Object.prototype.__proto__) function Fn() { this.test1 = function () { console.log('test1()') } } //console.log(Fn.prototype) Fn.prototype.test2 = function () { console.log('test2()') } var fn = new Fn() fn.test1() //test1() fn.test2() //test2() console.log(fn.toString()) //[object object] console.log(fn.test3) //undefined //fn.test3() /* 1. */ console.log(Fn. Prototype instanceof Object) // true console.log(Object.prototype instanceof Object) // false console.log(Function.prototype instanceof Object) // true /* 2.  All functions are instances of Function (including Function) */ console.log(function.__proto__ === function.prototype) /* 3. Object's prototype Object is the end of the prototype chain */ console.log(Object.prototype.__proto__) // nullCopy the code

3.6 == Constructor/prototype/instance object relationship (diagram)==

var o1=new Object();
var o2={ };
Copy the code

3.7 == Constructor/prototype/instance object relationship 2(diagram)==

function Foo( ){ }
Copy the code

InstanceOf keyword

1. How is instanceof judged?

A instanceof B

Instance keyword rule: == Returns true if B’s explicit prototype object is on the prototype chain of A, false== otherwise

2.Function is a self-generated instance of new

4.1 Case 1:

function Foo() {}
var f1 = new Foo()
console.log(f1 instanceof Foo) // true
console.log(f1 instanceof Object) // true
Copy the code

4.2 Case 2:

 console.log(Object instanceof Function) // true
 console.log(Object instanceof Object) // true
 console.log(Function instanceof Function) // true
 console.log(Function instanceof Object) // true

 function Foo() {}
 console.log(Object instanceof Foo) // false
Copy the code

5. Interview questions

5.1 Interview question 1: After familiarity, there is no need to draw a picture, to understand at a glance

 function A() {

      }
      A.prototype.n = 1

      var b = new A()

      A.prototype = {
        n: 2,
        m: 3
      }

      var c = new A()
      console.log(b.n, b.m, c.n, c.m) //1 undefined 2 3
Copy the code

5.2 Interview Question 2:

function F() {} Object.prototype.a = function () { console.log('a()') } Function.prototype.b = function () { Console. The log (' b () ')} var f = new f () f.a f.b () () / / an error f.a f.b () ()Copy the code

The key to this problem is to understand the final prototype chain diagram below