Js object inheritance

recently, I have been looking at Boss Ruan"s object inheritance, Javascript object-oriented programming (2): inheritance of constructors

, but I ran the code myself and found several problems. I don"t know what"s wrong. Three problems:
1, constructor apply

        //object
        function logObj(obj) {
            console.log("new OBJECT LOG-------------------------------");
            for(var prop in obj) {
                console.log(`${prop} == ${obj[prop]}`);
            }
        }
        function Person(name, sex) {
            this.name = name;
            this.sex = sex;
            this.fav = "read";
        }
        Person.prototype.say = function() { //
            console.log(`I"m ${this.name},and my sex is ${this.sex}`);
        }
                function People(name,sex,nation){
                    Person.apply(this,arguments);
                    this.nation = nation;
                }
                var me = new People("li","man","China");
                console.log(me);
                me.say();//

apply constructor inheritance mode, cannot get person"s say common method.
2, another inheritance method,

                function People(nation) {
                    this.nation = nation;
                }
                People.prototype = new Person();
                console.log(People.prototype.constructor);
                People.prototype.constructor = People;
                var me = new People("China");
                logObj(me);

you can get properties and public methods by inheriting the parent class instance, but the parent class property is undefined. How to modify the properties of the parent class in the constructor parameters of the subclass instance, for example, can name, be modified only through me.name
3, directly inheriting the prototype



        function extend(Child, Parent) {
            var F = function() {};
            F.prototype = Parent.prototype;
            Child.prototype = new F();
            Child.prototype.constructor = Child;
        }

        function People(nation) {
            this.nation = nation;
        }
        extend(People, Person);
        var he = new People("China");
        logObj(he);
        console.log(he.name);//undefined
        console.log(he.fav);  //undefined

found that this inheritance method can get the common method say, but cannot inherit the properties name and sex,fav of the parent Class.

it feels like everything is wrong, and there is a copy inheritance behind it. Errors are reported when adding new attributes, indicating that there is no such thing on the prototype chain.

//
        var Chinese = {
            nation: "",
            fav: "read"
        };
        var Doctor = {
            career: ""
        }

        function deepCopy(p, c) {
            var c = c || {};
            for(var i in p) {
                if(typeof p[i] === "object") {
                    c[i] = (p[i].constructor === Array) ? [] : {};
                    deepCopy(p[i], c[i]);
                } else {
                    c[i] = p[i];
                }
            }
            return c;
        }
        var Doctor = deepCopy(Chinese);
        Chinese.birthPlaces = ["", "", ""];
        Doctor.birthPlaces.push(""); //
        logObj(Chinese);
        logObj(Doctor);
Sep.08,2021

the way in which the apply constructor inherits, you can't get the say common method of person.
first of all, you need to understand what the constructor, new and this inside the constructor are
.
function Person(name, sex) {
    this.name = name;
    this.sex = sex;
    this.fav = 'read';
}

new Person () inside, first, an Object instance person {} is created. This points to this {}, and finally return this person instance.
when Person is executed alone, this this is meaningless. It reports an error in strict mode and points to window; in non-strict mode

.
function People(name,sex,nation){
    Person.apply(this,arguments);
    this.nation = nation;
}

Person.apply (this,arguments) just execute the Person method, and replacing the this inside the Person method with the this, in the People method is equivalent to copying

this.name = name;
this.sex = sex;
this.fav = 'read';

the prototype of the constructor in this way is independent of each other, and there is no inheritance relationship between the two types, so it is impossible to make instanceof true;
in order to make up for this shortcoming, we should introduce a second method to point People.prototype to the Person instance.
the combination of the two methods should look like this:

 function People(name,sex,nation){
    Person.apply(this,arguments);
    this.nation = nation;
}
People.prototype = new Person();
console.log(People.prototype.constructor);
People.prototype.constructor = People;

this inherits the methods on the parent prototype, while the properties are copied by themselves.
if we completely rewrite our constructor and inherit only the methods of the parent class, it is appropriate to use the third method (for example, if the attributes in the parent class are private).
copy inheritance is said to be inheritance, but it is actually an object copy, which has nothing to do with inheritance at all.
inheritance in js is implemented through prototype chain. I feel that this implementation is a bit "virtual". If you are interested, you can compare it with virtual table inheritance.


you should have misunderstood these methods: they are not different implementations of equivalent inheritance methods, but different implementations with their own flaws. What you notice is the flaw in these ways.


class People extends Person {} is not solved, so there is no need to struggle so much. It is inevitable that JavaScript, which is not a standard OOP, but implemented through prototypes, has all kinds of defects. Since ES6 provides extends , why bother with those defects.

Menu