理解原型

原型是一个对象。其它对象能够通过它实现属性继承。

不论什么一个对象都能够成为继承,全部对象在默认的情况下都有一个原型。由于原型本身也是对象,所以每一个原型自身又有一个原型。

不论什么一个对象都有一个prototype的属性。记为:__proto__。

每当我们定义一个对象,其__proto__属性就指向了其prototype。示比例如以下:

var foo = {
x: 10,
y: 20
};

即使我们不指定prototype,该属性也会预留。假设我们有明白指向的话。那么链表就连起来了。

须要注意的是,prototype自己也有指向,就是最高级的object.prototype。

示比例如以下:

var a = {
x: 10,
calculate: function (z) {
return this.x + this.y + z
}
};
var b = {
y: 20,
__proto__: a
}; var c = {
y: 30,
__proto__: a
}; // call the inherited method
b.calculate(30); // 60

使用原型

理解了原型的原理之后,怎样使用原型呢?或者说原型有什么作用呢?

一般的刚開始学习的人。在刚刚学习了主要的javascript语法后,都是通过面向函数来编程的。

例如以下代码:

var decimalDigits = 2,
tax = 5; function add(x, y) {
return x + y;
} function subtract(x, y) {
return x - y;
} //alert(add(1, 3));

通过运行各个函数来得到最后的结果。

可是利用原型,我们能够优化一些我们的代码,使用构造函数:

首先。函数本体中仅仅存放变量:

var Calculator = function (decimalDigits, tax) {
this.decimalDigits = decimalDigits;
this.tax = tax;
};

其详细的方法通过prototype属性来设置:

Calculator.prototype = {
add: function (x, y) {
return x + y;
}, subtract: function (x, y) {
return x - y;
}
};
//alert((new Calculator()).add(1, 3));

这样就能够通过实例化对象后进行对应的函数操作。

这也是一般的js框架採用的方法。

原型另一个作用就是用来实现继承。

首先。定义父对象:

var BaseCalculator = function() {
this.decimalDigits = 2;
}; BaseCalculator.prototype = {
add: function(x, y) {
return x + y;
},
subtract: function(x, y) {
return x - y;
}
};

然后定义子对象。将子对象的原型指向父元素的实例化:

var Calculator = function () {
//为每一个实例都声明一个税收数字
this.tax = 5;
}; Calculator.prototype = new BaseCalculator();

我们能够看到Calculator的原型是指向到BaseCalculator的一个实例上,目的是让Calculator集成它的add(x,y)和subtract(x,y)这2个function,另一点要说的是,因为它的原型是BaseCalculator的一个实例,所以无论你创建多少个Calculator对象实例,他们的原型指向的都是同一个实例。

上面的代码。执行以后,我们能够看到由于Calculator的原型是指向BaseCalculator的实例上的,所以能够訪问他的decimalDigits属性值,那假设我不想让Calculator訪问BaseCalculator的构造函数里声明的属性值,那怎么办呢?仅仅须要将Calculator指向BaseCalculator的原型而不是实例即可了。代码例如以下:

var Calculator = function () {
this.tax= 5;
}; Calculator.prototype = BaseCalculator.prototype;

在使用第三方库的时候。有时候他们定义的原型方法不能满足我们的须要,我们就能够自己加入一些方法。代码例如以下:

//覆盖前面Calculator的add() function
Calculator.prototype.add = function (x, y) {
return x + y + this.tax;
}; var calc = new Calculator();
alert(calc.add(1, 1));

原型链

对象的原型指向对象的父。而父的原型又指向父的父,这样的原型层层的关系。叫做原型链。

在查找一个对象的属性时。javascript会向上遍历原型链,直到找到给定名称的属性为止。当查找到达原型链的顶部,也即是Object.prototype。仍然没有找到指定的属性。就会返回undefined。

示比例如以下:

function foo() {
this.add = function (x, y) {
return x + y;
}
} foo.prototype.add = function (x, y) {
return x + y + 10;
} Object.prototype.subtract = function (x, y) {
return x - y;
} var f = new foo();
alert(f.add(1, 2)); //结果是3。而不是13
alert(f.subtract(1, 2)); //结果是-1

我们能够发现,subtrace是依照向上找的原则,而add则出了意外。原因就是,属性在查找的时候是先查找自身的属性,假设没有再查找原型。

说到Object.prototype,就不得不提它的一个方法。hasOwnProperty。

它能推断一个对象是否包括自己定义属性而不是原型链上的属性,它是javascript中唯一一个处理属性可是不查找原型链的函数。使用代码例如以下:

// 改动Object.prototype
Object.prototype.bar = 1;
var foo = {goo: undefined}; foo.bar; // 1
'bar' in foo; // true foo.hasOwnProperty('bar'); // false
foo.hasOwnProperty('goo'); // true

而为了推断prototype对象和某个实例之间的关系,又不得不介绍isPrototyleOf方法,演演示样例如以下:

alert(Cat.prototype.isPrototypeOf(cat2)); //true

最新文章

  1. Javascript字节转换
  2. (转)理解MySQL——索引与优化
  3. RabbitMQ小结
  4. hdu 5291 dp+优化 ****
  5. STM32 USB CAN 学习笔记 - 共享RAM的用法
  6. poj3020
  7. Hash Killer I II
  8. hdu 1596 find the safest road
  9. 牛顿迭代法求开根号。 a^1/2_______Xn+1=1/2*(Xn+a/Xn)
  10. 初学javascript《一》break和continue的标签问题
  11. MyBatis中<if test=" ">标签条件不起作用
  12. python判断字符串是字母 数字 大小写
  13. GMA Round 1 逃亡
  14. 微信小游戏 three.js jsonloader request:fail invalid url
  15. Windows Service application 初步探索
  16. JavaScript数组转字符串,字符串转数组
  17. [HNOI2012]矿场搭建 BZOJ2730 点双+结论
  18. DC组策略相关
  19. WebApi是轻量级的,WCF是重量级的,可以Api调用WCF,更灵活
  20. 自定义cscope-index

热门文章

  1. 紫书 习题 10-8 UVa 10622(gcd)
  2. 【模板】2-SAT 问题(2-SAT)
  3. unity SystemInfo类 获得电量battery
  4. 【DevExpress】GridControl添加按钮列并添加按钮事件
  5. php实现模拟登陆
  6. difference in physical path, root path, virutal path, relative virtual path, application path and aboslute path?
  7. OpenCV与Socket实现树莓派获取摄像头视频至电脑
  8. 21.MFC进制转换工具
  9. 有关R6034错误的思考
  10. RedHat Linux 多媒体学习指南 (共 36 部原创视频)