首页 > 软件开发 > JavaScript >

Javascript原型

来源:互联网 2023-03-16 23:56:12 版权归原作者所有,如有侵权,请联系我们

Javascript原型介绍及原型工作原理与相关应用brj办公区 - 实用经验教程分享!

方法/步骤

  • 1

    一、 初识原型brj办公区 - 实用经验教程分享!

    JS的引用类型会内置一个特殊的属性prototype。默认的prototype是object类型的,是引用类型。既然默认的prototype是object类型的,那么prototype也会有一个原型,并且指向object的原型。brj办公区 - 实用经验教程分享!

    另外补充一点,function的原型可直接访问,object的不行。brj办公区 - 实用经验教程分享!

    示例:brj办公区 - 实用经验教程分享!

    function SuperType(){};brj办公区 - 实用经验教程分享!

    SuperType.age=18;brj办公区 - 实用经验教程分享!

    SuperType.prototype.color=[“red”,”blue”];brj办公区 - 实用经验教程分享!

    var t1=new SuperType ();brj办公区 - 实用经验教程分享!

    t1.name=”hh”;brj办公区 - 实用经验教程分享!

    var t2=new SuperType ();brj办公区 - 实用经验教程分享!

    t2.qq=”aa”;brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    SuperType,t1,t2原型关系示意图:brj办公区 - 实用经验教程分享!

    Javascript原型brj办公区 - 实用经验教程分享!

  • 2

    定义function SuperType时,编译器会为其分配一个prototype属性,并在内存brj办公区 - 实用经验教程分享!

    中开辟一片区域用于存放SuperType的原型的数据,假设这片区域的地址为0xA。brj办公区 - 实用经验教程分享!

    然后让SuperType的prototype指向0xA。由SuperType创建出来的t1和t2的brj办公区 - 实用经验教程分享!

    prototype也指向内存地址0xA。如果有SuperType.prototype.color.push(“green”),则brj办公区 - 实用经验教程分享!

    t1和t2的color也会变为[“red”,”blue”,”green”]。因为SuperType,t1,t2的原型指brj办公区 - 实用经验教程分享!

    向的是同一个地址的数据。这个过程可以这么比喻:把原型比喻为你的银行卡账户,brj办公区 - 实用经验教程分享!

    假设有一万块钱。当有人盗刷你的银行卡,刷走了4000,然后你去银行查看你账brj办公区 - 实用经验教程分享!

    户余额,当然的会剩下6000。因为你跟盗刷你银行卡的人所持的银行卡指向的是brj办公区 - 实用经验教程分享!

    同一个账户。brj办公区 - 实用经验教程分享!

    SuperType.prototype.color.push(“green”)后,示意图如下:brj办公区 - 实用经验教程分享!

    Javascript原型brj办公区 - 实用经验教程分享!

  • 2
  • 3

    二、 原型链brj办公区 - 实用经验教程分享!

    其实在上面的示意图中,顺着箭头走,如Test—>Test的原型—>Object的原型,就是一条原型链了。当然t2—>Test的原型—>Object的原型也是一条原型链。下面对原形链进行补充,说明原型链在继承体系中是怎么工作的。brj办公区 - 实用经验教程分享!

    示例:brj办公区 - 实用经验教程分享!

    function SuperType(){};brj办公区 - 实用经验教程分享!

    SuperType.age=18;brj办公区 - 实用经验教程分享!

    SuperType.prototype.color=[“red”,”blue”];brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    function SubType(){}brj办公区 - 实用经验教程分享!

    SubType.property=”property”;brj办公区 - 实用经验教程分享!

    SubType.prototype=new SuperType();brj办公区 - 实用经验教程分享!

    SubType.prototype.test=function(){alert(“test”);}brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    function Child(){}brj办公区 - 实用经验教程分享!

    Child.prototype=new SubType();brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    var t1=new SuperType ();brj办公区 - 实用经验教程分享!

    t1.name=”hh”;brj办公区 - 实用经验教程分享!

    var t2=new SuperType ();brj办公区 - 实用经验教程分享!

    t2.qq=”aa”;brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    var s=new SubType();brj办公区 - 实用经验教程分享!

    var c=new Child();brj办公区 - 实用经验教程分享!

    注意,SubType的原型被重新赋值了,SubType.prototype=new SuperType();brj办公区 - 实用经验教程分享!

    所以SubType的原型是SuperType的一个对象实例。brj办公区 - 实用经验教程分享!

    上述代码的原型链示意图如下:brj办公区 - 实用经验教程分享!

    Javascript原型brj办公区 - 实用经验教程分享!

  • 4

    三、重置原型brj办公区 - 实用经验教程分享!

    要重置原型,只要对原型重新赋值即可。例如:brj办公区 - 实用经验教程分享!

    function Person(){}brj办公区 - 实用经验教程分享!

    Person.prototype={brj办公区 - 实用经验教程分享!

    name:”Leo”brj办公区 - 实用经验教程分享!

    }brj办公区 - 实用经验教程分享!

    需要注意的是,Person原型重写后,Person的原型为{ name:”Leo”}。{ name:”Leo”}是一个匿名的Object实例,所以其constructor,为Object。也就是说重写后Person的原型的constructor为Object。如果constructor很重要,可以为其增加一个constructor属性,如下:brj办公区 - 实用经验教程分享!

    Person.prototype={brj办公区 - 实用经验教程分享!

    name:”Leo”,brj办公区 - 实用经验教程分享!

    constructor:Personbrj办公区 - 实用经验教程分享!

    }brj办公区 - 实用经验教程分享!

    不过此时还会有一个问题,这样设置的constructor将会使constructor变成是可枚举的。所以,如果想让它变为不可枚举的,可用Object.defineProperty进行设置brj办公区 - 实用经验教程分享!

  • 5

    四、原型的动态性brj办公区 - 实用经验教程分享!

    示例:brj办公区 - 实用经验教程分享!

    function Person(){}brj办公区 - 实用经验教程分享!

    var p=new Person();brj办公区 - 实用经验教程分享!

    Person.prototype.sayHi=function(){alert(“Hi”);};brj办公区 - 实用经验教程分享!

    p.sayHi();//这里没问题,因为p在调用sayHi时,会先从自身找sayHi,找不到则会沿//着原形链去寻找,然后在Person的原型中找到了sayHi,于是就执行brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    原型动态性之-------重写原型的问题brj办公区 - 实用经验教程分享!

    function Person(){}brj办公区 - 实用经验教程分享!

    var p=new Person();brj办公区 - 实用经验教程分享!

    Person.prototype={brj办公区 - 实用经验教程分享!

    sayName: function(){alert(“Hi”);},brj办公区 - 实用经验教程分享!

    constructor:Personbrj办公区 - 实用经验教程分享!

    }brj办公区 - 实用经验教程分享!

    p.sayName();//此时将会报错,p没有sayName方法brj办公区 - 实用经验教程分享!

    这里为何p.sayName会报错,Person的原型不是有sayName么?brj办公区 - 实用经验教程分享!

    且看下面的示意图:brj办公区 - 实用经验教程分享!

    Javascript原型brj办公区 - 实用经验教程分享!

  • 6

    五、原型共享所引发的问题brj办公区 - 实用经验教程分享!

    原型的优点就是共享。例如:brj办公区 - 实用经验教程分享!

    function Person (){}brj办公区 - 实用经验教程分享!

    Person.prototype.sayName=function(){};brj办公区 - 实用经验教程分享!

    var p1=new Person ();brj办公区 - 实用经验教程分享!

    var p2=new Person ();brj办公区 - 实用经验教程分享!

    在原型中定义sayName函数,于是p1,p2对象有同一个sayName。而不会在内存中分配两次内存来分别存放p1的sayName和p2的sayName。而缺点也是由共享所致。共享对于函数而言,是合适的,但是对于其他属性而言,可能就会出问题。brj办公区 - 实用经验教程分享!

    示例如下:brj办公区 - 实用经验教程分享!

    function Person(){}brj办公区 - 实用经验教程分享!

    Person.prototype.color=[“red”,”green”];brj办公区 - 实用经验教程分享!

    var p1=new Person();brj办公区 - 实用经验教程分享!

    var p2=new Person();brj办公区 - 实用经验教程分享!

    alert(p1.color);//输出red,greenbrj办公区 - 实用经验教程分享!

    alert(p2.color); //输出red,greenbrj办公区 - 实用经验教程分享!

    p2.color.push(“blue”);brj办公区 - 实用经验教程分享!

    alert(p1.color); //输出red,green,blue。注意,这里我并没有更改p1的colorbrj办公区 - 实用经验教程分享!

    alert(p2.color); //输出red,green,bluebrj办公区 - 实用经验教程分享!

    这里我们可以发现,p2的color进行更改之后,p1的color也跟着更改,这正是原型共享所引发的问题brj办公区 - 实用经验教程分享!

  • 7

    六、原型链与instanceof实现原理brj办公区 - 实用经验教程分享!

    假设a instanceof b,那么会从a的原形链中找出是否有跟b的原型相等的原型,如果找到则返回true,否则返回false。brj办公区 - 实用经验教程分享!

    示例如下:brj办公区 - 实用经验教程分享!

    function SuperType(){}brj办公区 - 实用经验教程分享!

    function SubType(){}brj办公区 - 实用经验教程分享!

    function Test(){}brj办公区 - 实用经验教程分享!

    SubType.prototype=new SuperType();brj办公区 - 实用经验教程分享!

    var s=new SubType();brj办公区 - 实用经验教程分享!

    console.log(s instanceof SubType);//打出true,这是因为s的原型等于SubType的原型brj办公区 - 实用经验教程分享!

    SubType.prototype=new SuperType();brj办公区 - 实用经验教程分享!

    console.log(s instanceof SubType);//打出false,这是因为SubType的原型变了,而s还//是原来的SubType的原型brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    上面代码的工作过程是这样的:brj办公区 - 实用经验教程分享!

    先说s的原型:s由SubType构造而来,SubType原型由SuperType构造而来。所以有brj办公区 - 实用经验教程分享!

    这样的关系,brj办公区 - 实用经验教程分享!

    ①、s.prototype=SubType.prototype= new SuperType();brj办公区 - 实用经验教程分享!

    ②、s.prototype.prototype=SuperType.prototype;brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    于是第一个s instanceof SubType时,会先这样判断s.prototype是否跟brj办公区 - 实用经验教程分享!

    SubType.prototype是同一个对象,用表达式表示的话就是这样,判断brj办公区 - 实用经验教程分享!

    s.prototype==SubType.prototype,如果相等结果返回true。在第二次brj办公区 - 实用经验教程分享!

    s instanceof SubType时SubType.prototype重新new了一次,于是brj办公区 - 实用经验教程分享!

    s.prototype==SubType.prototype就返回false了。但是s的原形链还没到终点,于是再判断s.prototype.prototype==SubType.prototype,此时仍然是false,而s的原形链也已经到了终点,于是返回false,所以第二次s instanceof SubType的运算结果就是false。以此类推,如果是s instanceof SuperType那么会先这样brj办公区 - 实用经验教程分享!

    s.prototype==SuperType.prototype显然是false,于是沿着原形链,继续判断s.prototype.prototype==SuperType.prototype,此时返回true。于是brj办公区 - 实用经验教程分享!

    s instanceof SuperType的结果就是true。brj办公区 - 实用经验教程分享!

    brj办公区 - 实用经验教程分享!

    说明:brj办公区 - 实用经验教程分享!

    s是object类型,所以s的原型是不可以直接引用的,即s.prototype是会报错的,这里这么表示只是为了不想画图,又要表述方便,所以采用这种方式进行说明。brj办公区 - 实用经验教程分享!

  • 以上方法由办公区教程网编辑摘抄自百度经验可供大家参考!brj办公区 - 实用经验教程分享!


    标签: JAVASCRIPT

    办公区 Copyright © 2016-2023 www.bgqu.net. Some Rights Reserved. 备案号:湘ICP备2020019561号