JS技术

JavaScript之原型和原型链性能影响

字号+ 作者: 来源: 2014-11-16 22:20 我要评论( )

JavaScript之原型和原型链性能影响

      大多数JavaScript 代码以面向对象的形式编写。无论通过创建自定义对象还是使用内置的对象,诸如文档对象模型(DOM)和浏览器对象模型(BOM)之中的对象。因此,存在很多对象成员访问。
      对象成员包括属性和方法,在JavaScript 中,二者差别甚微。对象的一个命名成员可以包含任何数据类型。既然函数也是一种对象,那么对象成员除传统数据类型外,也可以包含一个函数。当一个命名成员引用了一个函数时,它被称作一个“方法”,而一个非函数类型的数据则被称作“属性”。
      正如本章前面所讨论过的,对象成员比直接量或局部变量访问速度慢,在某些浏览器上比访问数组项还要慢。要理解此中的原因,首先要理解JavaScript 中对象的性质。
      一、原形
      JavaScript 中的对象是基于原形的。原形是其他对象的基础,定义并实现了一个新对象所必须具有的成员。这一概念完全不同于传统面向对象编程中“类”的概念,它定义了创建新对象的过程。原形对象为所有给定类型的对象实例所共享,因此所有实例共享原形对象的成员。

      一个对象通过一个内部属性绑定到它的原形。Firefox,Safari,和Chrome 向开发人员开放这一属性,称作__proto__;其他浏览器不允许脚本访问这一属性。任何时候你创建一个内置类型的实例,如Object 或Array,这些实例自动拥有一个Object 作为它们的原形。
      因此,对象可以有两种类型的成员:实例成员(也称作“own”成员)和原形成员。实例成员直接存在于实例自身,而原形成员则从对象原形继承。考虑下面的例子:
      var book = {
            title: "High Performance JavaScript",
            publisher: "Yahoo! Press"
      };
      alert(book.toString()); //"[object Object]"
      此代码中,book 对象有两个实例成员:title 和publisher。注意它并没有定义toString()接口,但是这个接口却被调用了,也没有抛出错误。toString()函数就是一个book 对象继承的原形成员。处理对象成员的过程与变量处理十分相似。book.toString()被调用时,对成员进行名为“toString”的搜索,首先从对象实例开始,如果book 没有名为toString 的成员,那么就转向搜索原形对象,在那里发现了toString()方法并执行它。通过这种方法,booke 可以访问它的原形所拥有的每个属性或方法。
      你可以使用hasOwnProperty()函数确定一个对象是否具有特定名称的实例成员,(它的参数就是成员名称)。要确定对象是否具有某个名称的属性,你可以使用操作符in。例如:
      var book = {
            title: "High Performance JavaScript",
            publisher: "Yahoo! Press"
      };
      alert(book.hasOwnProperty("title")); //true
      alert(book.hasOwnProperty("toString")); //false
      alert("title" in book); //true
      alert("toString" in book); //true
      此代码中,hasOwnProperty()传入“title”时返回true,因为title 是一个实例成员。传入“toString”时返回false,因为toString 不在实例之中。如果使用in 操作符检测这两个属性,那么返回都是true,因为它既搜索实例又搜索原形。
      二、原形链
      对象的原形决定了一个实例的类型。默认情况下,所有对象都是Object 的实例,并继承了所有基本方法,如toString()。你可以用“构造器”创建另外一种类型的原形。例如:
      function Book(title, publisher){
            this.title = title;
            this.publisher = publisher;
      }
      Book.prototype.sayTitle = function(){
            alert(this.title);
      };
      var book1 = new Book("High Performance JavaScript", "Yahoo! Press");
      var book2 = new Book("JavaScript: The Good Parts", "Yahoo! Press");
      alert(book1 instanceof Book); //true
      alert(book1 instanceof Object); //true
      book1.sayTitle(); //"High Performance JavaScript"
      alert(book1.toString()); //"[object Object]"
      Book 构造器用于创建一个新的Book 实例。book1 的原形(__proto__)是Book.prototype,Book.prototype的原形是Object。这就创建了一个原形链,book1 和book2 继承了它们的成员。注意,两个Book 实例共享同一个原形链。每个实例拥有自己的title 和publisher 属性,但其他成员均继承自原形。当book1.toString()被调用时,搜索工作必须深入原形链才能找到对象成员“toString”。正如你所怀疑的那样,深入原形链越深,搜索的速度就会越慢。图2-11 显示出成员在原形链中所处的深度与访问时间的关系。
      虽然使用优化JavaScript 引擎的新式浏览器在此任务中表现良好,但是老的浏览器,特别是InternetExplorer 和Firefox 3.5,每深入原形链一层都会增加性能损失。记住,搜索实例成员的过程比访问直接量或者局部变量负担更重,所以增加遍历原形链的开销正好放大了这种效果。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • WEB前端教程-JavaScript里的类和继承

    WEB前端教程-JavaScript里的类和继承

    2016-01-21 15:28

  • 高性能动画“box-shadow”属性 - FedFun - 博客频道 - CSDN.NET FedFun 爱前端,乐分

    高性能动画“box-shadow”属性 - FedFun - 博客频道 - CSDN.NET FedF

    2015-12-14 16:15

  • JS开发者调查 - FedFun - 博客频道 - CSDN.NET FedFun 爱前端,乐分享,前端痴王海庆的博客!

    JS开发者调查 - FedFun - 博客频道 - CSDN.NET FedFun 爱前端,乐分

    2015-12-13 11:08

  • Jquery下编写流行的前端的应用源码_Javascript教程

    Jquery下编写流行的前端的应用源码_Javascript教程

    2015-10-01 09:24

网友点评
i