820笔记(构造函数和原型)

构造函数和原型

对象的三种创建方式

  • 字面量
var obj={}
  • new 关键字
var obj = new Object()
  • 构造函数创建
function Person(){
    this.name='zs'
    this.age=12
}
var p=new Person()
    <script>
        //1 字面量 一次只能创建一个对象
        var obj = { name: 'zs', age: 23 }  //一条数据,包含了两个字段

        //2 利用new Object创建 一次只能创建一个对象
        var obj1 = new Object()
        console.log(obj1)
        //两种方式向对象里添加内容
        obj1.name = '笑笑'
        obj1['age'] = 23

        //3 利用构造函数创建对象 创建一类对象(有共同属性和方法的对象)

        // 构造函数和普通函数的区别
        // 构造函数的首字母要大写;构造函数必须用new来创建对象
        // 一类学生 学生类 性别 年龄 成绩 学习 
        function Student(name, age, score) {
            this.name = name
            this.age = age
            this.score = score
            this.study = function () {
                console.log('好好学习')    //方法
            }
        }
        var s1 = new Student('zs', 12, 100)
        //先执行new Student创建一个对象,然后把这个对象给s1,再调用这个函数,给函数传递实参,给s1动态地添加属性
        var s2 = new Student('ls', 32, 89)
    </script>

构造函数存在的问题

每创建一个对象,就会生成一个新的函数,存在浪费内存的问题

解决方法:所有对象使用同一个函数,这样就节省了内存,怎么做呢?---原型

构造函数原型prototype

构造函数通过原型分配的函数,是所有对象共享的

javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个prototype属性就是一个对象,这个对象的所有属性和方法都会被构造函数所拥有

我们可以把那些不变的方法,直接定义在prototype对象上,这样所有的对象实例就可以共享这些方法

实例化对象

每一个实例对象都可以访问它构造函数的原型对象中的成员

    <script>
        /* 
        实例成员 就是构造函数内部通过this添加的成员
        */
        function Star(uname, age) {
            this.uname = uname  //这个uname就是一个实例成员
            this.age = age
            this.sing = function () {
                console.log('唱歌')
            }
        }

        //实例化对象  new创建的对象就是一个实例
        var ldh = new Star('刘德华', 18)    //实例成员只能通过实例化的对象来访问
        console.log(ldh.uname)
        console.log(ldh.age)
    </script>
通过原型动态添加对象

一般情况下,我们把公共的属性定义到构造函数里;公共的方法放在原型对象上

        function Star(uname, age) {
            this.uname = uname  //这个uname就是一个实例成员
            this.age = age   //构造函数给的自身的属性
            }
       //使用原型对象创建一次就可以了
       //通过动态的方式给原型对象添加成员
		Star.prototype.sing=function(){   
    		console.log('唱歌')
		}
		var zxy=new Star('张学友',28)
		zxy.sing()  //sing在原型对象里
对象原型
1 实例对象都会有一个属性 _proto_ 指向构造函数的prototype原型对象
2 之所以我们对象可以使用构造函数prototype原型的属性和方法,就是因为对象有_proto_属性的存在

3 _proto_对象原型和原型对象prototype是等价的
4 对象原型的意义在于为对象的查找机制提供了一个方向,或者说是一条路线 

5 _proto_是一个非标准的属性。在开发过程中,不可以使用这个属性 _proto_,它只是内部指向原型对象prototype

    <script>
        function Star(uname, age) {
            this.uname = uname  //这个uname就是一个实例成员
            this.age = age
        }
        Star.prototype.sing = function () {
            console.log('唱歌')
        }
        var ldh = new Star('刘德华', 18)
        var zxy = new Star('张学友', 26)
        ldh.sing()
        zxy.sing()

        //对象身上系统自己添加一个_proto_指向我们构造函数的原型对象prototype
        console.log(ldh._proto_ === star.prototype)  //true
        /* 方法的查找机制
        首先先看ldh对象身上是否有sing方法,如果有就执行这个对象上的sing;如果没有sing,因为有_prototype_的存在,就去构造函数原型对象prototype上找sing这个方法 
        */
    </script>
constructor 构造函数
对象原型(_proto_)和构造函数(prototype)原型对象里面都有一个属性,constructor属性我们称为构造函数,因为它指回构造函数本身

constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数
一般情况下,对象的方法都在构造函数的原型对象中设置,如果有多个对象的方法,我们可以给原型对象采取对象的形式赋值,但是这样会覆盖构造函数原型对象原来的内容,这样修改后的原型对象constructor就不再指向当前构造函数了。此时,我们可以在修改后的原型对象中,添加一个constructor指向原来的构造函数
    <script>
        function Star(uname, age) {
            this.uname = uname  //这个uname就是一个实例成员
            this.age = age
        }
        //如果有多个对象的方法,可以给原型对象采取对象的形式进行赋值
        Star.prototype = {
            //constructor值改变了
            //我们可以在修改后的原型对象中,添加一个constructor指向原来的构造函数
            constructor: Star,
            sing: function () {
                console.log('唱歌')
            },
            movie: function () {
                console.log('电影')
            },
        }
        var ldh = new Star('刘德华', 18)
        var zxy = new Star('张学友', 26)
        console.log(ldh._proto_)
        console.log(Star.prototype)
    </script>
原型链
每一个实例对象有一个_proto_属性,指向构造函数的原型对象
构造函数的原型对象,也是一个对象
这样一层一层往上找,就形成了原型链

posted on 2022-08-23 21:37  星野落  阅读(24)  评论(0编辑  收藏  举报

导航