zoukankan      html  css  js  c++  java
  • javascript之原型

    一、初识原型

          JS的引用类型会内置一个特殊的属性prototype。默认的prototype是object类型的,是引用类型。既然默认的prototype是object类型的,那么prototype也会有一个原型,并且指向object的原型。

    另外补充一点,function的原型可直接访问,object的不行。

    示例:

    function SuperType(){};
    
    SuperType.age=18;
    
    SuperType.prototype.color=[“red”,”blue”];
    
    var t1=new SuperType ();
    
    t1.name=”hh”;
    
    var t2=new SuperType ();
    
    t2.qq=”aa”;

    SuperType,t1,t2原型关系示意图:

    定义function SuperType时,编译器会为其分配一个prototype属性,并在内存中开辟一片区域用于存放SuperType的原型的数据,假设这片区域的地址为0xA。然后让SuperType的prototype指向0xA。由SuperType创建出来的t1和t2的prototype也指向内存地址0xA。如果有SuperType.prototype.color.push(“green”),则t1和t2的color也会变为[“red”,”blue”,”green”]。因为SuperType,t1,t2的原型指向的是同一个地址的数据。这个过程可以这么比喻:把原型比喻为你的银行卡账户,假设有一万块钱。当有人盗刷你的银行卡,刷走了4000,然后你去银行查看你账户余额,当然的会剩下6000。因为你跟盗刷你银行卡的人所持的银行卡指向的是同一个账户。

        SuperType.prototype.color.push(“green”)后,示意图如下:

    二、 原型链

    其实在上面的示意图中,顺着箭头走,如Test—>Test的原型—>Object的原型,就是一条原型链了。当然t2—>Test的原型—>Object的原型也是一条原型链。下面对原形链进行补充,说明原型链在继承体系中是怎么工作的。

    示例:

    function SuperType(){};
    SuperType.age=18;
    SuperType.prototype.color=[“red”,”blue”];
    
    function SubType(){}
    SubType.property=”property”;
    SubType.prototype=new SuperType();
    SubType.prototype.test=function(){alert(“test”);}
    
    function Child(){}
    Child.prototype=new SubType();
    var t1=new SuperType ();
    t1.name=”hh”;
    var t2=new SuperType ();
    t2.qq=”aa”;
    
    var s=new SubType();
    var c=new Child();

    注意,SubType的原型被重新赋值了,SubType.prototype=new SuperType();

    所以SubType的原型是SuperType的一个对象实例。

    上述代码的原型链示意图如下:

    三、重置原型

    要重置原型,只要对原型重新赋值即可。例如:function Person(){} Person.prototype={ name:”Leo” } 需要注意的是,Person原型重写后,Person的原型为{ name:”Leo”}。{ name:”Leo”}是一个匿名的Object实例,所以其constructor,为Object。也就是说重写后Person的原型的constructor为Object。如果constructor重要,可以为其增加一个constructor属性,如下:Person.prototype={          name:”Leo”,          constructor:Person}不过此时还会有一个问题,这样设置的constructor将会使constructor变成是可枚举的。所以,如果想让它变为不可枚举的,可用Object.defineProperty进行设置。

    四、原型的动态性

    示例:

    function Person(){}
    
    var p=new Person();
    
    Person.prototype.sayHi=function(){alert(“Hi”);};
    
    p.sayHi();//这里没问题,因为p在调用sayHi时,会先从自身找sayHi,找不到则会沿//着原形链去寻找,然后在Person的原型中找到了sayHi,于是就执行

    原型动态性之-------重写原型的问题

    function Person(){}
    
    var p=new Person();
    
    Person.prototype={
    
    sayName: function(){alert(“Hi”);},
    
    constructor:Person
    
    }
    
    p.sayName();//此时将会报错,p没有sayName方法

    这里为何p.sayName会报错,Person的原型不是有sayName么?

    且看下面的示意图:

    五、原型共享所引发的问题

    原型的优点就是共享。例如:

    function Person (){}
    Person.prototype.sayName=function(){};
    var p1=new Person ();
    var p2=new Person ();

    在原型中定义sayName函数,于是p1,p2对象有同一个sayName。而不会在内存中分配两次内存来分别存放p1的sayName和p2的sayName。而缺点也是由共享所致。共享对于函数而言,是合适的,但是对于其他属性而言,可能就会出问题。示例如下:

    function Person(){}
    Person.prototype.color=[“red”,”green”];
    var p1=new Person();
    var p2=new Person();
    alert(p1.color);//输出red,green
    alert(p2.color); //输出red,green
    p2.color.push(“blue”);
    alert(p1.color); //输出red,green,blue。

    注意,这里我并没有更改p1的color;alert(p2.color); //输出red,green,blue这里我们可以发现,p2的color进行更改之后,p1的color也跟着更改,这正是原型共享所引发的问题。

    六、原型链与instanceof实现原理

    假设a instanceof b,那么会从a的原形链中找出是否有跟b的原型相等的原型,如果找到则返回true,否则返回false。

    示例如下:

    function SuperType(){}
    function SubType(){}
    function Test(){}
    SubType.prototype=new SuperType();
    var s=new SubType();
    console.log(s instanceof SubType);//打出true,这是因为s的原型等于SubType的原型
    SubType.prototype=new SuperType();
    console.log(s instanceof SubType);//打出false

    示意图如下:(省略了百度上的文字说明而改为图片说明)

    以上是百度经验里关于 javascript原型 的介绍。

    延伸:

    1.构造函数中的return

    构造函数在没有return的情况下新的实例默认返回undefined;如果构造函数中有return语句,

    分两种情况:

    • return 基本类型,返回函数
    • return 对象,返回对象。

    2.原型模式的执行流程

    • 先查找构造函数实例里的属性或方法,如果有,就立即返回。
    • 如果构造函数的实例没有,就去它的原型对象里找,如果有,就立即返回

     拜读了风雨后见彩虹的文章

  • 相关阅读:
    Kubernetes 集成研发笔记
    Rust 1.44.0 发布
    Rust 1.43.0 发布
    PAT 甲级 1108 Finding Average (20分)
    PAT 甲级 1107 Social Clusters (30分)(并查集)
    PAT 甲级 1106 Lowest Price in Supply Chain (25分) (bfs)
    PAT 甲级 1105 Spiral Matrix (25分)(螺旋矩阵,简单模拟)
    PAT 甲级 1104 Sum of Number Segments (20分)(有坑,int *int 可能会溢出)
    java 多线程 26 : 线程池
    OpenCV_Python —— (4)形态学操作
  • 原文地址:https://www.cnblogs.com/Merrys/p/8012661.html
Copyright © 2011-2022 走看看