构造函数、原型对象和实例对象

135 阅读1分钟

构造函数、原型对象和实例对象的三角关系

  1. prototype : 属于构造函数,指向原型对象

    作用:解决资源浪费+变量污染

  2. __proto__ : 属于实例对象,指向原型对象

    作用:可以让实例对象访问原型中的成员

  3. constructor: 属于原型对象,指向构造函数

    作用:可以让实例对象 知道自己被哪一个构造函数创建的

  <script>
        //1.◆构造函数
        function Person(name, age) {
            this.name = name
            this.age = age
        }

        //2.◆原型对象
        Person.prototype.eat = function () {
            console.log('吃东西')
        }

        //3.◆实例对象
        let p1 = new Person('大女儿', 5)

        //4.◆检查原型 : 
        //(1)先通过实例对象找构造函数
        console.log(p1.__proto__.constructor) //[Function: Person]
        //(2)构造函数和原型对象一一对应关系
        console.log(p1.__proto__ === Person.prototype)//true
 </script>

原型使用注意点

  1. 哪些属性可以放在构造函数中?

    名字、年龄、性别、分数每个对象都不同,所以放入构造函中

  2. 哪些属性可以放在原型中?

    所有实例对象共有的成员(方法等)

  3. 对象访问原型的规则 : 就近原则

    对象访问成员的时候,优先访问自身的。 如果自身没有才会访问原型的

<script>
        //◆构造函数
        function Person(name, age) {
            this.name = name
            this.age = age
        }

        //◆原型对象
        //所有的人都是哺乳动物,所以 type 可以放在原型中
        Person.prototype.type = '哺乳动物'
        //每一个人都可以吃东西,这个方法是大家共有的,就可以放在原型中                              
        Person.prototype.eat = function () {
            console.log('吃东西')
        }

        //◆实例对象
        let p1 = new Person('大女儿', 5)

        //◆实例对象也可以动态添加属性
        p1.type = '大美女'

        console.log(p1.type)//大美女
        console.log(p1)//Person {name: '大女儿', age: 5, type: '大美女'}
</script>
  1. 原型是可以覆盖的

    实例对象访问覆盖前的原型还是覆盖后的原型,取决于这个实例对象在什么时候创建

    • 覆盖前创建 : 实例对象的原型就是覆盖前的原型
    • 覆盖后创建 : 实例对象的原型就是覆盖后的原型
 <script>
        //◆构造函数
        function Person(name, age) {
            this.name = name
            this.age = age
        }

        //◆原型对象                                 
        Person.prototype.eat = function () {
            console.log('覆盖前原型-1')
        }

        //◆实例对象
        let p1 = new Person('大女儿', 5)

        //◆使用新对象把原来的原型给覆盖掉
        Person.prototype = {
            eat: function () {
                console.log('覆盖后原型-2')
            }
        }

        let p2 = new Person('小女儿', 1)

        p1.eat()//覆盖前原型-1
        p2.eat()//覆盖后原型-2
</script>

什么是原型链

JavaScript 原型:每个对象都会在其内部初始化一个属性,就是 prototype (原型)

原型链:当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的 prototype,如果还没找到就会在构造函数的 prototype__proto__中查找,这样一层一层向上查找,就会形成一个链式结构,我们称为原型链