Javascript原型

Javascript原型介绍及原型工作原理与相关应用

操作方法

  • 01

    一、       初识原型 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原型关系示意图:

  • 02

    定义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”)后,示意图如下:

  • 03

    二、 原型链 其实在上面的示意图中,顺着箭头走,如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的一个对象实例。 上述代码的原型链示意图如下:

  • 04

    三、重置原型 要重置原型,只要对原型重新赋值即可。例如: 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进行设置

  • 05

    四、原型的动态性 示例: 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么? 且看下面的示意图:

  • 06

    五、原型共享所引发的问题 原型的优点就是共享。例如: 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也跟着更改,这正是原型共享所引发的问题

  • 07

    六、原型链与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,这是因为SubType的原型变了,而s还//是原来的SubType的原型 上面代码的工作过程是这样的: 先说s的原型:s由SubType构造而来,SubType原型由SuperType构造而来。所以有 这样的关系, ①、s.prototype=SubType.prototype= new SuperType(); ②、s.prototype.prototype=SuperType.prototype; 于是第一个s instanceof SubType时,会先这样判断s.prototype是否跟 SubType.prototype是同一个对象,用表达式表示的话就是这样,判断 s.prototype==SubType.prototype,如果相等结果返回true。在第二次 s instanceof SubType时SubType.prototype重新new了一次,于是 s.prototype==SubType.prototype就返回false了。但是s的原形链还没到终点,于是再判断s.prototype.prototype==SubType.prototype,此时仍然是false,而s的原形链也已经到了终点,于是返回false,所以第二次s instanceof SubType的运算结果就是false。以此类推,如果是s instanceof SuperType那么会先这样 s.prototype==SuperType.prototype显然是false,于是沿着原形链,继续判断s.prototype.prototype==SuperType.prototype,此时返回true。于是 s instanceof SuperType的结果就是true。 说明: s是object类型,所以s的原型是不可以直接引用的,即s.prototype是会报错的,这里这么表示只是为了不想画图,又要表述方便,所以采用这种方式进行说明。

(0)

相关推荐

  • vs2008 JavaScript 语法提示(Intellisense)功能

    Visual Studio 2008将是一个非常激动人心的版本,包含了成堆的强大的功能。其中一个新特性就是更加完善的支持对JavaScript的调试及IntelliSense功能。Visual Stu ...

  • 移动UI/UX设计师和PM使用的原型工具

    无论是做网页设计还是手机移动端设计,开始制作时都是先从原型框架开始设计,最初设计师们可能在纸上画原型图,但现在已有很多先进的工具能让我快速生成原型并能实现一些交互设计功能。因此,设计达人网整理一些适用 ...

  • 2018年你用对合适的原型工具了吗?

    说起软件原型,有些人也许会对更广泛意义上的原型比较熟悉.其实两者本质也是一样的东西.原型设计在绝大多数的产品阶段中已不可或缺.经过思路,数据,信息,需求,评估等相关信息的收集和整理后,设计师往往需要将 ...

  • Javascript实现页面跳转的几种方式

    JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...

  • IE内核浏览器如何开启或禁用js(javascript)

    JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...

  • Javascript继承

    操作方法 01 Javascript继承 一直想对Javascript再次做一些总结,正好最近自己写了一个小型Js UI库,总结了一下Js的继承机制,在网上也看了一些前辈们博客里的总结,感觉分析不是特 ...

  • Java 和 JavaScript 是什么关系?

    JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...

  • 5个最好的javascript调试工具

    操作方法 01 JavaScript主要被用作一种语言来实现客户端浏览器的一部份,目的是为了提供更好的用户界面.JavaScript是已经被应用于许多现代的网站,也有很多现代网络应用程序. JavaS ...

  • 使用网摘提供的Javascript收藏方式

    经常浏览网页的网友肯定都有使用网络书签的习惯,这种方式非常方便但也有缺点就是需要安装浏览器插件,这样或多或少都需要占用内存,有没有更好的解决方法呢,答案是有的。 如果你是一个一级网虫,你一定经常使用网 ...