首页 > 技术文章 > 原型链

niuyaomin 2020-05-08 02:05 原文

    在典型的oop的语言中都存在类的概念,对象就是类的模板,对象就是类的实例,但是在ES6之前,JS并没有引入类的概念,在ES6之前对象不是基于类创建的,而是用一种称为构造函数的特殊函数来定义对象和他们的特征
// 创建一个构造函数
        // 构造函数首字母需要大写
        // 实例成员就是构造函数内部通过this添加成员uname,age,sing就是实例成员
        // 实例成员只能通过实例化的对象来访问

        function Star(uname, age){
            // 这里的this指向的是实例对象谁是构造函数的实例就会指向谁
            this.name = uname;
            this.age = age;
            // this.sing = function(){
            //     console.log(this.uname);
            // };
        };

        // 原型的作用就是共享方法
        Star.prototype.sing = function(){
                console.log(this.uname);
                console.log("aaa");
        };
        var ldh = new Star("刘德华",18);
        var zxy = new Star("张学友",10);
        
        

        Star.prototype.sing();// 构造函数只能通过一步一步来调用sing方法
        
        
        for (var i in ldh) {
            console.log(i);//name,age,sing
        };

        // 静态成员 只能在构造函数本身上添加的成员
        // 静态成员 只能通过构造函数本身来访问
        Star.sex = "男";
        console.log(Star.sex);//

        // 构造函数的方法虽然很好用,但是存在浪费内存的问题,每创建一个实例对象都会开辟一个内存空间
        console.log(ldh.sing === zxy.sing);// false

        // 构造函数通过原型分配的函数是所有对象所共享的
        // js种规定,每一个构造函数里面都有一个prototype属性,指向另一个对象。注意这个prototype就是一个对象,这个对象的属性和方法,都会被构造函数所拥有。
        // 我们可以把那些不变的方法,直接定义在prototype对象上面,这样所有的对象的实例就可以共享这些方法
        console.log(Star.prototype);// {sing: ƒ, constructor: ƒ}
        // 在我们实例对象身上系统自动添加一个__proto__指向构造函数的原型对象Star.prototype
        console.log(ldh.__proto__);// {sing: ƒ, constructor: ƒ}
        console.log(Star.prototype === ldh.__proto__);// true 放法的查找规则就近原则,首先看看对象身上是否都有sing方法,如果有就执行这个对象上的sing没有就去通过实例的隐示原型到构造函数的显示原型上面查找,最后找到Object.prototype的里面没有的话就返回undefined
        // __proto__的意义就在于为实例对象的查找机制提供了一个方向,或者说是一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性
        ldh.__proto__.a = "aa"
        console.log(ldh.a);// "aa"可以定义但是实际开发不能用
        // constraint返回构造函数
        console.log(Star.prototype.constructor);
        // 很多情况下,我们需要手动的利用construct这个属性指向原来的构造函数
        Star.prototype = {
            chi: function(){
                console.log("吃");
            },
            he: function(){
                console.log("喝");
            },
            constructor: Star
            //如果我们修改了原来的原型对象,则必须手动的利用construct指向原来的函数
        };
        console.log(ldh.__proto__);// {a: "aa", sing: ƒ, constructor: ƒ}
        console.log(Star.prototype);// {chi: ƒ, he: ƒ}


        
        for (var i in ldh) {
            console.log(i);//name,age,sing
        };

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

推荐阅读