最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • (JS)原型对象prototype

    正文概述 掘金(前端五月天)   2020-11-30   438

    原型对象prototype

    ES6引入了class语法,这里暂不涉及。

    原型对象概述

    1.构造函数的缺点

    JavaScript通过构造函数生成新对象,因此构造函数可以视为一个模版,用于生成实例对象以及该实例对象的属性与方法。

    function Animal(type,name){
        this.type=type;
        this.name=name;
    }
    var pp=new Animal("pig","pp");
    pp.type;// pig
    pp.name;// pp
    

    上面代码中,构造函数Animal定义了typename属性,所有由函数Animal构造的实例对象,都具有这两个属性。

    缺点

    通过构造函数为定义实例对象的属性,虽然很方便,但是,同一个构造函数构建的实例对象之间,无法共享属性,会造成资源的浪费

    function Animal(type,name){
        this.type=type;
        this.name=name;
        this.voice=function(){
            console.log("hanghang");
        };
    }
    var pp=new Animal("pig","pp");
    var uu=new Animal("pig","uu");
    pp.voice===uu.voice ;//false
    

    上面代码表示,ppuu是构造函数Animal的两个实例,他们有着相同的voice方法,但是该方法是生成在每个实例对象上,有几个实例对象就要生成几次,这样就导致了资源的浪费。 因为该方法在不同实例对象间,执行结果都是一样的

    在此背景下,JavaScript引出了一个解决方法,那就是原型对象(prototype)

    2. prototype属性的作用

    简单来说,当属性和方法定义在原型(prototype)上时,那么所有的实例对象都能共享,不仅节省了内存,还体现了实例对象之间的联系。

    如何为对象指定原型?

    JavaScript规定,每个函数都有一个prototype属性,指向一个对象。

    function f(){}
    type of f.prototype; //object
    

    上述代码中,函数f默认有prototype属性,指向一个对象。

    对于普通函数来说,这个属性可有可无,但是当这个属性定义在构造函数上时,该属性会自动成为实例对象的原型。

    function Animal(type,name){
        this.type=type;
        this.name=name;
        
        };
    }
    Animal.prototype.voice=function(){
                  console.log("hanghang");
     }
    var pp=new Animal("pig","pp");
    var uu=new Animal("pig","uu");
    pp.voice(); //hanghang
    uu.voice(); //hanghang
    

    上面代码中,voice是定义在构造函数Animal原型上的方法,可以被uupp两个实例对象共享。

    原型对象上的方法不是实例对象自身的方法,如果对其进行修改,变动会体现在所有的实例对象上。

    Animal.prototype.voice=4;
    pp.voice; //4
    uu.voice; //4
    

    上述代码表示,改变对构造函数原型上的方法,变动会体现在所有的实例对象上

    只有当该实例对象没有某个属性或方法时,它才会去原型上找,否则将直接使用实例对象自带的

    pp.voice="hanghang";
    

    上面代码中,实例对象ppvoice属性改为了"hanghang",使得它不再去原型对象读取voice属性。

    总结一下,原型对象的作用,就是定义所有实例对象共享的属性和方法。这也是它被称为原型对象的原因,而实例对象可以视作从原型对象衍生出来的子对象。

    Animal.prototype.walk = function () {
      console.log(this.name + ' is walking');
    };
    

    上面代码中,Animal.prototype对象上面定义了一个walk方法,这个方法将可以在所有Animal实例对象上面调用。

    3.原型链

    产生原因

    JavaScript 规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain):对象到原型,再到原型的原型……

    按照这个思路,所有对象的原型最终都可以追溯到Object.prototype。也就是说,所有的对象都可以继承定义在Object.prototype下的方法如valueOftoString等。

    Object.prototype对象的原型是null,本文不详细介绍

    读取对象的某个属性时,JavaScript 引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined

    如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overriding

    注意,一级级向上,在整个原型链上寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链。

    举例来说,如果让构造函数的prototype属性指向一个数组,就意味着实例对象可以调用数组方法。

    var MyArray = function () {};
    
    MyArray.prototype = new Array();
    MyArray.prototype.constructor = MyArray;
    
    var mine = new MyArray();
    mine.push(1, 2, 3);
    mine.length // 3
    mine instanceof Array // true
    

    上面代码中,mine是构造函数MyArray的实例对象,由于MyArray.prototype指向一个数组实例,使得mine可以调用数组方法(这些方法定义在数组实例的prototype对象上面)。

    最后那行instanceof表达式,用来比较一个对象是否为某个构造函数的实例,结果就是证明mineArray的实例。

    上面代码还出现了原型对象的constructor属性,这个属性默认指向prototype对象所在的构造函数。

    参考链接

    JavaScript Modules: A Beginner’s Guide-----Preethi Kasireddy


    最后,希望能和大家一起进步!

    起源地下载网 » (JS)原型对象prototype

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元