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类和原型学习笔记的更多相关文章

  1. js类、原型——学习笔记

    js 内置有很多类,我们用的,都是从这些类实例化出来的. function Object () {} function Array () {} function String () {} functi ...

  2. 《零基础学JavaScript(全彩版)》学习笔记

    <零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...

  3. 《JavaScript语言精粹》学习笔记

    一.in的用法 for...in 枚举一个对象的所有可枚举属性 检测DOM/BOM属性 if ("onclick" in elem) { // 元素支持onclick } if ( ...

  4. 《JavaScript权威指南》学习笔记 第六天 开始学习DOM了。

    昨天学习了window对象的一些方法.window对象主要是针对当前视窗的操作.window对象提供了一些列API来帮助我们了解当前窗口的信息.例如history对象可以让我们获取浏览历史.nvaig ...

  5. 《JavaScript高级程序设计》学习笔记12篇

    写在前面: 这12篇博文不是给人看的,而是用来查的,忘记了什么基础知识,点开页面Ctrl + F关键字就好了 P.S.如果在对应分类里没有找到,麻烦告诉我,以便尽快添上.当然,我也会时不时地添点遗漏的 ...

  6. 对Javascript 类、原型链、继承的理解

    一.序言   和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...

  7. JavaScript原型学习笔记

    1 理解JavaScript原型 什么是原型? 原型是一个对象,其他对象可以通过它实现属性继承. 任何一个对象都可以成为原型么? 是 哪些对象有原型 所有的对象在默认的情况下都有一个原型,因为原型本身 ...

  8. 《JavaScript高级程序设计》学习笔记(5)——面向对象编程

    欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第六章内容. 1.面向对象(Object ...

  9. 《JavaScript权威指南》学习笔记 第五天 window对象的方法。

    前天和昨天大致浏览了犀牛书的函数.类与模块.正则表达式.JavaScript扩展.以及服务端的js.这些方面对于我目前的水平来说比较难,一些最基本的概念都不能领会.不过最复杂的知识占用平时使用的20% ...

随机推荐

  1. 【编程练习】poj1111

    Image Perimeters Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8632   Accepted: 5168 ...

  2. android AlarmManager讲解

    Android系统闹钟定时功能框架,总体来说就是用数据库存储定时数据,有一个状态管理器来统一管理这些定时状态的触发和更新.在Andriod系统中实现定时功能,最终还是要用到系统提供的AlarmMana ...

  3. Spark:大数据的电花火石!

    什么是Spark?可能你很多年前就使用过Spark,反正当年我四六级单词都是用的星火系列,没错,星火系列的洋名就是Spark. 当然这里说的Spark指的是Apache Spark,Apache Sp ...

  4. 详解EBS接口开发之WIP模块接口

    总体说明 文档目的 本文档针对WIP模块业务功能和接口进行分析和研究,对采用并发请求方式和调用API方式分别进行介绍 内容 WIP模块常用标准表简介 WIP事物处理组成 WIP相关业务流程 WIP相关 ...

  5. MyBatis进阶(一)运行原理

    初次学习MyBatis,自己花了不少时间,理解一件事物是需要时间的.经过多次反复的理解,你的认知能力就可以得到提升.以下是学习MyBatis的一些理解认识,技术理解上若有不当之处,敬请朋友们提出宝贵意 ...

  6. Java-IO之总框架

    在Java IO中我们会经常提到输入流和输出流,流是一种抽象的数据总称,本质是能够进行数据的传输.按照流的方向分为:输入流和输出流.按照流中处理数据的单位,可以将其区分为:字节流和字符流.在Java中 ...

  7. 第三方ProgressHUD进度条 技术分享

    创建一个进度辅助视图: 初始化: - (void)viewDidLoad { [super viewDidLoad]; <span style="color: rgb(255, 0, ...

  8. VS2012 发布网站步骤

    VS2012中发布网站的方式与以往有了不同,前面的版本发布如图 而2012点publish的时候弹出框有所不同,这边需要新建一个profile名字随便起,发布的方式有好几种, 当然不同的方式配置不同, ...

  9. java的hashcode(结合hashset讲解)

    equals()跟hashcode()都可以用来比较对象.hashcode通过不同对象有不同的散列码来比较两个对象. hashcode方法把对象放到一个对象容器进行查找,算法好坏直接影响容器的存取效率 ...

  10. 基于Bootstrap的Metro风格模板

    这几天在看Bootstrap的一些书,这里整理一下书中的一些模板,方便以后使用. 1.BootMetro http://www.guoxiaoming.com/bootmetro/ 2.Bootswa ...