This is the 20th day of my participation in the August Text Challenge.More challenges in August

preface

Yesterday we mainly inherited the knowledge of the first paragraph, today we mainly do exercises, directly open.

Object-oriented – Inheritance (PART 1)

Object-oriented – Inheritance (Middle)

First, prototype chain inheritance – practice

The exercises in this section are actually quite simple, as mentioned in previous articles. Just a quick explanation.

Let’s write three constructors here: Animal, Person, Student

Among them:

  • Animal instance property has name, age; The prototype method has eat, run
  • The Person instance property has Job and the prototype method has Jump
  • Student has className on the instance property and study on the stereotype method

Also some students feel that the text seems not to understand what the meaning, I have prepared the picture

First, what does a constructor look like? What are instance attributes? What is a prototype approach? Regardless of the first two you might want to think about, there’s something called prototype that should immediately come to mind. Right? So the code is easy to write.

So start writing the code. The comments are all written in the code.

// ------------- Animal ------------ //

function Animal(name, age) {
    // Instance properties
    this.name = name;
    this.age = age;
}

// Prototype method
Animal.prototype.eat = function () {
    console.log('eat');
};

Animal.prototype.run = function () {
    console.log('run');
}

// ------------- Person ------------ //

function Person(job) {
    // Instance properties
    this.job = job;
}

// Prototype method
Person.prototype.jump = function () {
    console.log('jump');
};


// ------------- Student ------------ //

function Student(className) {
    // Instance properties
    this.className = className;
}

// Prototype method
Student.prototype.study = function () {
    console.log('learning');
}

Copy the code

Inheritance, inheritance, how can you be complete without inheritance? Now let’s implement inheritance

    <! --Animal-->
    <script>
        function Animal(name, age) {
            this.name = name;
            this.age = age;
        }

        Animal.prototype.eat = function () {
            console.log(this.name + 'eat');
        };

        Animal.prototype.run = function () {
            console.log(this.name + 'run');
        }
    </script>
    <! --Person-->
    <script>
        function Person(job, name, age) {
            // 1. Change this with constructor inheritance
            Animal.call(this, name, age);
            this.job = job;
        }

        // 2. Prototype-chain inheritance and parasitic inheritance
        function Temp() {}
        Temp.prototype = Animal.prototype;

        / / Temp instance
        var personPrototype = new Temp();
        // Modify the constructor direction
        personPrototype.constructor = Person;
        Person.prototype = personPrototype;

        // attention attention attention.... Here's the prototype method for Person
        Person.prototype.jump = function () {
            console.log(this.name + 'jump');
        };
    </script>
    <script>
        var p = new Person('cook'.'Ming'.18);
        console.log(p);
        p.run();
        p.eat();
        p.jump();
    </script>

    <! --Student-->
    <script>
        function Student(className) {
            this.className = className;
        }

        Student.prototype.study = function () {
            console.log('learning');
        }
    </script>
Copy the code

So let’s see what happens, right

Here we can see that __proto__ refers to Animal, and even a Person instance can call Animal’s run and eat methods.

Ii. Inheritance – Application Exercises (Extending built-in Objects)

Method 1

Add properties and methods directly to objects dynamically

var arr = [1.2.3];
arr.run = function () {
    console.log('run');
};
arr.run();

var arr2 = [2];
arr2.run();
Copy the code

Disadvantages:

  1. If you operate on many objects, you cannot share them
  2. The code is redundant

Way 2

Add methods directly to the Array prototype object

Array.prototype.push = function () {
    console.log('run');
};

var arr = [1.2.3];
arr.push('111');  / / run
console.log(arr); / / [1, 2, 3]

var arr2 = [2];
arr2.push('2222'); / / run
console.log(arr2); / / [2]
Copy the code

Disadvantages: Overlays may occur

Why does push output a run instead of a 4? The ARR output is not [1, 2, 3, “111”]. This is the downside of adding the Array prototype object directly, creating an override operation.

Methods 3

Provide a new constructor

Modify the stereotype of the constructor to point to the stereotype object as an array in order to get the properties and methods in the array.

Problem: The contents of the array prototype object are still modified

Optimization:

A prototype object is just an object

You can create an object directly from Array and assign a value to the newly created function prototype object

function MyArray() {}
MyArray.prototype = new Array(a); MyArray.prototype.run =function () {
    console.log('run');
};

var arr2 = new MyArray();
console.log(arr2); // MyArray()
arr2.run(); / / run
Copy the code

Three, knowledge supplement

1. Review

  • Function of theprototypeattribute
    • Each function has a prototype property that by default points to an empty Object (called: prototype Object).
    • The prototype object has a property constructor that points to the function object
  • A prototype objectAdd attributes (usually methods)
    • All instance objects of a function automatically have properties (methods) in the stereotype

2. Call and apply

The two methods are the methods on the prototype object of Function

Both functions do the same thing and can be implemented using borrowed methods

Parameters:

  • The first argument is the object calling the method (the object of the this binding inside the function).

  • Second parameter

    • Call: parameter list
    • An array of the apply:

Example:

  • Call (the real object that calls the method, parameter 1, parameter 2, parameter 3);

  • Object 1. method. Apply (the real object that calls the method, [parameter 1, parameter 2, parameter 3…] )

3. This summary

This — > always refers to an object

How a function is called

  • 001 calls this– > the current object as a method on the object

  • 002 calls this– >window as a normal function

  • 003 as constructor and new use this– > constructor inside the newly created object

  • 004 Is called by call or apply (function context call) this– > first argument

Inheritance – Copy properties

1. Manually copy copies

Iterate over one object’s key-value pairs and dynamically add them to another object

var obj = {
    name: 'Jack'.age: 19
};
var copyObj = {};

for (var key in obj) {
    copyObj[key] = obj[key];
}

obj.name = 'Tom';
console.log(obj); // {name: "Tom", age: 19}
console.log(copyObj); // {name: "Tom", age: 19}
Copy the code

2. Object.assign

Syntax: object. assign(parameter 1, parameter 2, parameter 3..)

The first argument is the target object, followed by the object to which the property is copied

var obj = {
    name: 'Jack'.age: 19
};
var copyObj = {};

Object.assign(copyObj, obj, {
    address: 'Beijing'
});

obj.name = 'Tom';

console.log(obj); // {name: "Tom", age: 19}
console.log(copyObj); // {name: "Jack", age: 19, address: "Beijing "}
Copy the code

Inheritance – Copy properties – deep copy

disadvantages

If the value of an attribute is a reference type, the child object and the parent object share a piece of data, and changes to one object affect the other

The solution

The difference between deep/shallow copies is the handling of reference values

  • Shallow copy, a direct copy of the address

  • Deep copy – Indicates the specific content of the copy address

Deep copy implementation ideas

  • 01 provides a function with two arguments (meta-object, object to copy properties of)

  • The function checks if the first argument has a value, and initializes an empty object if it has no value

  • 03 for.. In loop to variable 2

    • 001 Check what type is the current attribute value

    • 002 If it is a value type, copy the assignment directly

    • 003 If it is a reference type, then the method is called again to internally copy all the attributes of the object

The code is as follows:

// 1. The object to copy
var obj = {
    name: 'Jack'.age: 18.friends: ['Ming'.'flower'].goodFri: {
        name: 'Rose'.age: 16.adress: 'Beijing'.hobby: [{
            name: 'badminton'
        }, {
            name: Table tennis}]}};function deepCopyObj2NewObj(fromObj, toObj) {
    // Check whether the first argument in the function has a value.
    // Initialize an empty object if there is no value
    for (var key in fromObj) {
        var fromValue = fromObj[key];
        if(! isObj(fromValue)) { toObj[key] = fromValue; }else {
            // If it is a reference type, then the method is called again to internally copy all the attributes of the object
            var temObj = new fromValue.constructor;
            deepCopyObj2NewObj(fromValue, temObj);
            toObj[key] = temObj
        }
    }
}

function isObj(obj) {
    return obj instanceof Object;
}

function isArr(obj) {
    return Array.isArray(obj);
    // return Object.prototype.toString.call(obj) === '[object Array]'
}

var newObj = {};
deepCopyObj2NewObj(obj, newObj);

obj.goodFri.hobby[0] ['category'] = 'ball';  // Will not be copied

console.log('obj ==> ', obj);
console.log('newObj ==> ', newObj);
Copy the code

Take a look at the console output

Here the exercise is also done, object-oriented inheritance is over! I wonder if you have any gains?