Javascript 对象原型& 原型链

JS 对象原型和原型对象

JS构造函数创建对象的缺陷

instance 在这里插入图片描述

上面的例子中 console.log(ldh.sing === zxy.sing);为false , 对于相同的方法,存储的地址不同

  • 构造函数存在严重的内存浪费,如果想要所有的对象使用同一个函数需要使用到prototype. JS规定,每个函数都有一个prototype属性,指向另一个对象。构造函数的prototype对象比较特殊,我们通常讲的prototype就是指构造函数的prototype我们可以把那些不变的方法,直接定义在prototype对象上 这样所有的对象实例就可以共享这些方法
  • prototype 是一个静态成员 可以看到下面例子中的Star.prototype.sing(ldh.username);是undefined sing . 静态中成员的this 没有意义。

在这里插入图片描述

instance
   <script>
        function Star(username, age) {
            this.username = username;
            this.age = age;
            /* this.sing = function () {
                console.log(this.username + ' sing');
            } */

        }
        //static member
        Star.gender = 'male';
        console.log(Star.gender);
        //prototype
        Star.prototype.sing = function () {
            console.log(this.username + ' sing');
        }

        //instance 
        var ldh = new Star('liu', 60);
        var zxy = new Star('zhang', 60);
        console.log(Star.prototype.sing === ldh.sing);
        console.log(ldh.sing === zxy.sing);
        Star.prototype.sing(ldh.username);
        ldh.sing();
    </script>
  • 结果如下:
    在这里插入图片描述

为什么在prototype中定义的函数可以在实例中直接调用?

接上面的例子,在prototype中添加的sing ,可以使用ldh.sing调用呢?
我分别打印了ldh 实例和Star构造函数的属性,可以看到实例中的__proto__和prototype 相同

  • proto 称为对象原型,指向原型对象 prototype ldh.proto===Star.prototype为True
  • 不同的是 对象原型 是实例成员而原型对象是静态成员
  • 对象原型(proto)的作用是为对象的查找机制提供了一个方向,但是它本身是一个非标准属性,在实际开发中,不可以使用这个属性

原型对象的constructor

从上面的分析可以知道 所有的对象原型(proto)都是指向prototype的。而prototype中的constructor是构造函数本身(看图)

当我们需要在prototype中添加多个公用方法,而给prototype赋值时 需要重新给constructor 赋值。表明创建对象的构造函数

 //覆盖prototype 并重置构造函数
        Star.prototype = {
            constructor: Star,
            sing: function () {
                console.log('sing');
            },
            moive: function () {
                console.log('moive');
            }
        }
        var ldh = new Star('liu', 60);
        console.log(Star.prototype);
        console.log(ldh.__proto__);

原型链

按照上面的实例,我们可以推导出下面的原型链 在这里插入图片描述
JS中对象成员的查找是沿着原型链依次向上的,知道object为止

拓展方法

我们可以操作已有类型的prototype 来拓展已有类型的方法
以数组类型为例:

<script>
        Array.prototype.sum = function () {
            var sum = 0;
            for (let i = 0; i < this.length; i++) {
                sum += this[i];
            }
            return sum;
        }
        var arr = [2, 3, 4, 5];
        console.log(arr.sum());

    </script>

结论

实验和查资料,得出结论

  • 所有的JavaScript 对象都有__proto__(对象的原型),指向构造函数的原型对(prototype)
  • 所有原型对象都有一个constructor属性,指向其构造函数,所以这里是一个环,构造函数又有一个prototype属性来指向其对象原型。
  • 构造函数中都有原型对象(prototype)的静态成员,来共享属性和方法给构造函数的实例。
  • 所有的函数都有prototype 这句话值得商榷,built-in类型的函数就没有

在这里插入图片描述
为什么内置对象的函数没有prototype?
看StackOverflow 的文章https://stackoverflow.com/questions/14169384/why-do-built-in-functions-not-have-a-prototype-propertybuilt-in 没有prototype

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值