浅谈对JavaScript原型的理解

说到JavaScript原型,我硬是花了几个月才把这个概念吃透。

原型与对象的关系就好比是印章和印章印出的印一样,我们必须要聊到的两个属性是__proto__和prototype。

   Object.prototype.Show = function() {
            console.log("Hello World!");
        }

        var obj = {
            "eat": function() {
                console.log("ok");
            }
        }

        obj.Show();
<span style="white-space:pre">	</span>console.log(obj.prototype);//undefined
        console.log(obj.__proto__ === Object.prototype);

首先说说对象字面量,每一个对象都有一个__proto__,这个属性关联着Object.prototype的,于是如果我们想让所有的对象都有特定的属性或者方法,我们就可以在Object.prototype上面挂接相应的属性即可,并且,在以上代码中,我们可以看出,非函数对象是不具有prototype这个属性的。

然后,说说prototype,这个是函数对象特有的属性(JavaScript中,万物皆对象)。

我们以构造函数的形式创建对象,一般都是这样的套路:

  function ObjCreator() {

            this.tell = function() {
                console.log("Hello World!");
            }

        }
        var obj = new ObjCreator();
        obj.tell();
        console.log(obj.__proto__===ObjCreator.prototype);//true
我们惊人的发现obj.__proto__===ObjCreator.prototype,这样,构造函数创建的对象给到对象变量上,于是我们的对象获得构造函数及其原型对象上所定义的所有属性,再进一步,我们在输出 console.log(ObjCreator.prototype.__proto__ === Object.prototype);,这个居然是true,构造函数的原型对象关联着Object的原型对象,那么,JavaScript的原型链,我们已经搞清楚一半了。在这里,如果我们想要继承,就可以直接修改原型链即可:

  function ObjCreator() {

            this.tell = function() {
                console.log("Hello World!");
            }

        }


        function Child(){


        };


        Child.prototype=new ObjCreator();

这样,以后Child构造函数创造的对象,将会拥有所有ObjCreator实例的方法和属性。

继续扯,

  console.log(Child.__proto__ === Function.prototype);这个也是true,说明构造函数的__proto__关联着函数原型对象,那么如果我们在函数原型对象上添加方法,那么构造函数就会拥有这些方法,那么,如果这个构造函数是系统定义的呢?那么不就意味着我们可以向JavaScript内置对象中扩展新的功能了吗?于是,便有了这样的代码

 Function.prototype.method = function(name, fn) {
            if (!this.prototype[name]) {
                this.prototype[name] = fn;//保证每一个对象都要有相应的方法。
                console.log(this);
            }

        }
<span style="white-space:pre">	</span>//挂接方法
        Number.method("ToInt", function() {

            return this > 0 ? Math.floor(this) : Math.ceiling(this);

        });

        console.log((10 / 3).ToInt());//3

最后,我们再打印一下Function.prototype.__proto__,它关联着Object.prototype。

于是,所有的谜题都解开了,对象通过__proto__关联着它的原型对象(继续关联它的原型对象),实现复杂的JavaScript原型链,构造函数通过"函数名.prototype"在其中插了一脚,使得我们理解原型变得困难,prototype只在函数对象中存在,并且,当我们使用构造函数new的时候,相当于新建一个对象,然后把构造函数中属性和方法以及原型对象所有的属性和方法复制到这个对象里面去,返回给我们(假如我们不使用new的话,写东西就给到了window对象上了)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值