深入理解javascript之原型
理解原型
原型是一个对象。其它对象能够通过它实现属性继承。
不论什么一个对象都能够成为继承,全部对象在默认的情况下都有一个原型。由于原型本身也是对象,所以每一个原型自身又有一个原型。
不论什么一个对象都有一个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
深入理解javascript之原型的更多相关文章
- 理解JavaScript 的原型属性
1.原型继承 面向对象编程可以通过很多途径实现.其他的语言,比如 Java,使用基于类的模型实现: 类及对象实例区别对待.但在 JavaScript 中没有类的概念,取而代之的是一切皆对象.JavaS ...
- 三张图较为好理解JavaScript的原型对象与原型链
最近从网上看到别人详细得讲解了js的原型对象和原型链,看完感觉是看得最清晰的一个,于是,摘录到自己博客里 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与_ ...
- 理解 JavaScript 对象原型、原型链如何工作、如何向 prototype 属性添加新的方法。
JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板.从原型继承方法和属性.原型对象也可能拥有原型, ...
- 理解JavaScript的原型链
1. 什么是对象 在JavaScript中,对象是属性的无序集合,每个属性存放一个原始值.对象或函数. 1.1 创建对象 在JavaScript中创建对象的两种方法: ① 字面上: var myObj ...
- 如何理解JavaScript的原型和原型链
在现在的业务开发中,应该很少人在写原生JavaScript了,大家都一股脑地扑在各个框架上.本来,这些框架对于业务和开发者来说是一种福音,减少了各种各样的开发痛点,但是带来的负面问题就是对于开发者来说 ...
- 简单理解javascript的原型prototype
原型和闭包是Js语言的难点,此文主要讲原型. 每一个方法都有一个属性是 prototype 每一个对象都有一个属性是 _proto_ 一旦定义了原型属性或原型方法,则所有通过该构造函数实例化出来的所有 ...
- [我的理解]Javascript的原型与原型链
一.原型与原型链的定义 原型:为其他对象提供共享属性的对象 注:当构造器创建一个对象,为了解决对象的属性引用,该对象会隐式引用构造器的"prototype"属性.程序通过const ...
- 理解Javascript的原型和原型链
前言 本文2088字,阅读大约需要13分钟. 总括: 结合实例阐述了原型和原型链的概念并总结了几种创建对象的方法,扩展原型链的方法. 参考文章:The Secret Life of Objects,继 ...
- 【深入理解javascript】原型
1.一切都是对象 一切(引用类型)都是对象,对象是属性的集合 typeof函数输出的一共有几种类型,在此列出: function show(x) { console.log(typeof(x)); / ...
随机推荐
- 【LeetCode-面试算法经典-Java实现】【063-Unique Paths II(唯一路径问题II)】
[063-Unique Paths II(唯一路径问题II)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Follow up for "Unique Pa ...
- IIS 无法读取配置节"system.web.extensions",由于它缺少节声明
作者:jiankunking 出处:http://blog.csdn.net/jiankunking 今天在本地安装iis.搭建站点,应用程序的时候报错以下的错误: server错误 Internet ...
- jFinal 关联数据库操作
1.建数据库(我用的是oracle数据库,其他的相对也差不多) -- Create table create table CLASSES ( classesid NUMBER not null, cl ...
- 关于自适应的矩形css布局
在面试中遇到的问题,做一个自适应的宽高2:1的矩形,这个问题考察了padding的细节,padding-bottom的百分比值,相对的是该盒模型的height,设置矩形之后,里面的内容如果太多会溢出, ...
- HDU 5375 Gray Code 动归
题意:给你一串不确定的二进制码,其对应的格雷码的每一位有对应的权值,问转换成的格雷码的能取到的最大权值是多少. 思路:没有思路,乱搞也AC #pragma comment(linker, " ...
- 突破极限 解决大硬盘上安装Sco Unix新思路
突破极限 解决大硬盘上安装Sco Unix新思路 [url]http://os.51cto.com/art/200809/89750.htm[/url] 硬盘越做越大,然我喜欢让我忧.10 ...
- centos中mysql 安装以及配置,建库
1.检测系统内部有没有安装其他的mysql数据库 rpm -qa | grep mysql 然后如果有的话删除这些mysql yum remove 查出来的所有名字 2.彻底删除系统中mysql的目录 ...
- pythong中的全局变量的调用和嵌套函数中变量的使用
全局变量调用:想要在自定义的函数中使用全局变量,就得要在函数用关键字global声明,然后就可以对全局变量进行修改.嵌套函数中的变量的调用:要在嵌套的变量中,使用nonlocal的声明'''num = ...
- 对string的一些扩展函数
对string作了一些扩展,包含string转化为int.string转化为double.string转化为bool.打印系统当前时间.但没有解决数据溢出的问题,请大神帮忙解决! //头文件 /*pa ...
- CCNA Cloud CLDFND 210-451 QUIZ: Server Virtualization
Author:海峰 http://weibo.com/344736086 http://yanheven.github.io/ http://blog.csdn.net/yanheven1 1.Whi ...