在JavaScript中,所有函数都会拥有一个叫做prototype的属性,默认初始值为“空”对象(没有自身属性的对象)。

  1、原型属性

  如下所示,简单地定义一个函数:

    function foo(a, b){

      return a * b;

    }

  这时,就可以像访问其他对象一样访问该函数的属性,而这些属性中就包括prototype属性,它的初始值是一个“空”对象,

可以看成是:foo.prototype = {}。

  我们可以赋予这个空对象一些方法和属性,这并不会对foo函数本身造成什么影响,只有当foo()作为构造器(即构造函数)使用时,这些属性才会起作用。

  下面来看看如何利用原型添加方法与属性。

  2、利用原型添加方法与属性以及使用原型的方法与属性

  首先,构建一个具体的构造器函数Gadget():

 function Gadget(name, color){
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'I am a ' + this.color + ' ' + this.name;
};
}

  然后,利用构造器函数的prototype属性来为其增加两个属性(price和rating)和一个方法(getInfo),

  方法一:

 Gadget.prototype.price = 100;
Gadget.prototype.rating= 3;
Gadget.prototype.getInfo = function(){
return 'Rating: ' + this.rating + ', price: ' + this.price;
};

  方法二:

 Gadget.prototype = {
price: 100,
rating: 3,
getInfo: function(){
return 'Rating: ' + this.rating + ', price: ' + this.price;
}
}

  现在,使用该构造器来新建对象并访问之前定义的那些属性和方法:

 //创建一个对象
var newtoy = new Gadget('webcam', 'black');
//访问之前定义的属性
newtoy.name; //输出为 webcam newtoy.color; //输出为 black new.whatAreYou(); //输出为 I am a black webcam newtoy.price; //输出为 100 newtoy.rating; //输出为 3 newtoy.getInfo(); //输出为 Rating: 3, price: 100

  对于原型来说,最重要的一点就是它的“实时”性,由于JavaScript几乎所有对象都是通过传引用的方式来传递的,因此我们所创建的每个新对象实体中并没有一份属于自己原型副本,这也就意味着可以随时修改prototype属性,并且由同一构造器创建的所有对象的prototype属性也会同时改变(甚至还会影响在修改之前就已经创建了的那些对象)。

  如果在此时继续向上面例子中的原型再添加一些方法,即便newtoy对象在吸食添加的方法定义之前就已经被创建了,但newtoy对象依然可以访问新增的方法。

  我们不仅可以在相关的原型对象中添加新的方法和属性,甚至可以用自定义对象来完全替换掉原有的原型对象。但要注意,原型的声明是有先后顺序的,所以重写的原型会切断之前的原型。

  3、自身属性与原型属性

  回到上面的例子,首先来看看原型链的执行模式:当对象newtoy访问某个属性是,例如name属性,JavaScript引擎会遍历该对象的所有属性,并查找name属性,如果找到了就会立即返回,因为构造器函数中,确实定义了这个属性。而如果newtoy访问的是price属性,JavaScript引擎依然会查询该对象的所有属性,但是该对象中没有rating属性,此时脚本引擎就会去查询用于创建当前对象的构造器函数的原型(等价于直接访问 newtoy.constructor.prototype)。如果再原型中找到了该属性,就立即返回。如果依然没有找到,则会继续搜索其原型的原型,以此类推,知道搜索到Object.prototype。

  如果对象的自身属性与原型属性同名,那么返回的将是自身属性设置的值,因为对象自身属性的优先级高于原型属性。

  如果要判断一个属性时自身属性还是原型属性,可以使用 hasOwnProperty()方法来实现。若返回值为true,则说明是对象的自身属性;返回false,说明是对象的原型属性。

  附上一本参考书:《JavaScript面向对象编程指南(第2版)》

最新文章

  1. linux常用命令-文件处理命令
  2. mysql ERROR 1062: ALTER TABLE causes auto_increment resequen
  3. ue4 重新生成ide project文件的命令行
  4. 在android中用跑马灯的效果显示textview
  5. Linux的学习--系统目录
  6. Java堆、栈和常量池
  7. Android Studio MultiDex 分包碰到的坑
  8. Server 2003序列号
  9. .net面试题(.Net+Html+Javascript)
  10. Codeforces Round #313 (Div. 2) C. Gerald's Hexagon
  11. Unity3D常用 API 之实例化与销毁
  12. Redis缓存项目应用架构设计一
  13. NPOI 笔记
  14. 2017百度软研(C++)
  15. 创建http.Server实例,端口占用就换个端口
  16. Two Sum I & II & III & IV
  17. JavaWeb:脚本标识
  18. mybatis下的分页,支持所有的数据库
  19. 关于vs设置其他主题配色问题
  20. thinkphp中table方法

热门文章

  1. loj #2026. 「JLOI / SHOI2016」成绩比较
  2. 洛谷P3674 小清新人渣的本愿(莫队)
  3. Python 文件和异常
  4. CompletionService详解
  5. loj #6261 一个人的高三楼 FFT + 组合数递推
  6. 线段树 SP2713 GSS4 - Can you answer these queries IV暨 【洛谷P4145】 上帝造题的七分钟2 / 花神游历各国
  7. 用rc.local工具开机自启动
  8. react 中文文档案例六 (表单)
  9. javascript中的一元操作符
  10. NFS网络储存系统