javascript类和原型学习笔记
js中类的所有实例对象都从同一个原型对象上继承属性。我们可以自己写一个对象创建的工厂方法来来“模拟”这种继承行为:
//inherit()返回一个继承自原型对象p的属性的性对象
//这里使用ECMAScript5中的Object.create()函数
//如果不存在该函数,则使用另一种方法
function inherit(p){
if(p == null) throw TypeError();
if(Object.create)
return Object.create(p);
var t = typeof p;
if(t !== "object" && t!=="function")
throw TypeError();
function f(){};
f.prototype = p;
return new f();
}
代码中Object.create方法是在ECMAScript5中定义的,它创建一个新的对象,其中第一个参数是这个对象的原型:
var x = Object.create({x:1,y:2});
var y = Object.create(Object.prototype);//和{}或new Object()类似
下面模拟了一个类的构造函数:
function range(from,to){
var r = inherit(range.methods);
r.from = from;
r.to = to;
return r;
}
range.methods = {
includes:function(x){
return this.from <= x && x <= this.to;
},
foreach:function(f){
for(var x = Math.ceil(this.from);x <= this.to;x++)
f(x);
},
toString:function(){
return "(" + this.from + "..." + this.to + ")";
}
}
//我们可以向下面这样创建range对象以及调用它的方法
var r = range(1,3);
r.includes(2);
r.foreach(console.log);
console.log(r);
接下来我们用js的标准的new方法来创建相同的对象:
//类的构造函数约定首字母大写
//注意函数结尾不用return something代码
function Range(from,to){
this.from = from;
this.to = to;
}
//方法内容和前面一样,省略
Range.prototype = {
includes:function(x){...},
foreach:function(f){...},
toString:function(){...}
};
//同样给出创建和使用的代码
var r = new Range(1,3);
r.includes(2);
r.foreach(console.log);
console.log(r);
以上代码遵循了一个编程约定:定义构造函数即是定义类,首字母需要大写,普通函数和方法的首字母皆为小写。
还有要注意的是,第一段代码原型是range.methods,这种命名可以是任意的;而第二段代码中原型是Range.prototype,这个名称是必须的。对Range()构造函数的调用会自动使用Range.prototype作为新Range对象的原型。
每个js函数(ECMAScript5中的Function.bind()方法返回的函数除外)都自动拥有一个prototype属性,该属性的值为一个对象,该对象包含唯一一个不可枚举属性constructor,该属性的值味一个函数对象:
var f = function(){};
var p = f.prototype;
var c = p.constructor;
c === f //must true!对于任意函数f,有f.prototype.constructor === f;
以上可以认为constructor是以指回其构造函数的反向”指针”,由于constructor方法在对象的原型对象中,所以可以用任意对象来调用:
var obj = new F();
obj.constructor === F; //must true!
需要注意的是,以上第2个例子中Range类使用了一个新的对象重写了预定义的Range.prototype对象,但是这个新定义的原型对象不含有constructor属性,因此Range类的实例中也不含有constructor属性,我们可以给原型显示添加一个构造函数:
Range.prototype = {
constructor:Range,
//same codes...
};
还有一种方法是使用预定义的原型对象,域定义的原型对象包含constructor属性:
Range.prototype.includes = function(x){...};
Range.prototype.foreach = function(f){...};
Range.prototype.toString = function(){...};
javascript类和原型学习笔记的更多相关文章
- js类、原型——学习笔记
js 内置有很多类,我们用的,都是从这些类实例化出来的. function Object () {} function Array () {} function String () {} functi ...
- 《零基础学JavaScript(全彩版)》学习笔记
<零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...
- 《JavaScript语言精粹》学习笔记
一.in的用法 for...in 枚举一个对象的所有可枚举属性 检测DOM/BOM属性 if ("onclick" in elem) { // 元素支持onclick } if ( ...
- 《JavaScript权威指南》学习笔记 第六天 开始学习DOM了。
昨天学习了window对象的一些方法.window对象主要是针对当前视窗的操作.window对象提供了一些列API来帮助我们了解当前窗口的信息.例如history对象可以让我们获取浏览历史.nvaig ...
- 《JavaScript高级程序设计》学习笔记12篇
写在前面: 这12篇博文不是给人看的,而是用来查的,忘记了什么基础知识,点开页面Ctrl + F关键字就好了 P.S.如果在对应分类里没有找到,麻烦告诉我,以便尽快添上.当然,我也会时不时地添点遗漏的 ...
- 对Javascript 类、原型链、继承的理解
一.序言 和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...
- JavaScript原型学习笔记
1 理解JavaScript原型 什么是原型? 原型是一个对象,其他对象可以通过它实现属性继承. 任何一个对象都可以成为原型么? 是 哪些对象有原型 所有的对象在默认的情况下都有一个原型,因为原型本身 ...
- 《JavaScript高级程序设计》学习笔记(5)——面向对象编程
欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第六章内容. 1.面向对象(Object ...
- 《JavaScript权威指南》学习笔记 第五天 window对象的方法。
前天和昨天大致浏览了犀牛书的函数.类与模块.正则表达式.JavaScript扩展.以及服务端的js.这些方面对于我目前的水平来说比较难,一些最基本的概念都不能领会.不过最复杂的知识占用平时使用的20% ...
随机推荐
- 【Netty源码分析】Netty服务端bind端口过程
这一篇博客我们介绍一下Netty服务端绑定端口的过程,我们通过跟踪代码一直到NIO原生绑定端口的操作. 绑定端口操作 ChannelFuture future = serverBootstrap.bi ...
- 14 Fragment 注意点
API 过时问题 API 23过时 public void onAttach(Activity activity)替换为public void onAttach(Context context) 注意 ...
- GDAL使用插件方式编译HDF4、HDF5以及NetCDF的bug修改
GDAL库中提供了很方便的插件机制来扩展支持的数据格式,比如HDF4.HDF5.NetCDF.FileGDB.Postgre.Oralce等等.都可以通过插件的方式来使得GDAL支持相应的格式.最近将 ...
- android问题:Installation error: INSTALL_FAILED_CONFLICTING_PROVIDER
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/24196143 Installation error: INSTALL_FAILED_C ...
- 百度地图隐藏缩放控件比例尺Logo
对于百度地图最新版V3.7.3,以前的隐藏控件方法失效,可用以下方法隐藏: 1.隐藏缩放控件: mMapView.showZoomControls(false); 2.隐藏比例尺: mMapView. ...
- J2EE进阶(四)Spring配置文件详解
J2EE进阶(四)Spring配置文件详解 前言 Spring配置文件是用于指导Spring工厂进行Bean生产.依赖关系注入(装配)及Bean实例分发的"图纸".Java EE程 ...
- Linux:alias永久生效
alias(中文称为"别名")允许使用更加简短的名称来重新定义 Linux 中的 Shell 命令,从而简化命令行的输入. 如果经常与 CLI 打交道,那么使用 alias 不仅会 ...
- ROS_Kinetic_17 使用V-Rep3.3.1(vrep_ros_bridge)
ROS_Kinetic_17 使用V-Rep3.3.1(vrep_ros_bridge) https://github.com/lagadic/vrep_ros_bridge v-rep也有官网也有教 ...
- RabbitMQ消息队列(六):使用主题进行消息分发
在上篇文章RabbitMQ消息队列(五):Routing 消息路由 中,我们实现了一个简单的日志系统.Consumer可以监听不同severity的log.但是,这也是它之所以叫做简单日志系统的原因, ...
- PA 创建项目
---- 创建项目 DECLARE l_orig_project_id NUMBER := 6; l_prj_num VARCHAR2(240) := 'CXYTEST001'; l_start_da ...