关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JavaScript »JavaScript之原型深入详解

    JavaScript之原型深入详解

    2015-12-23 00:00:00 出处:souche
    分享

    理解原型

    原型是一个对象,其他对象可以通过它实现属性继承。任何一个对象都可以成为继承,所有对象在默认的情况下都有一个原型,因为原型本身也是对象,所以每个原型自身又有一个原型。任何一个对象都有一个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
    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    电脑屏幕不小心竖起来了?别慌,快捷键搞定

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    IT头条

    Synology 更新 ActiveProtect Manager 1.1 以增强企业网络弹性和合规性

    00:43

    新的 Rubrik Agent Cloud 加速了可信的企业 AI 代理部署

    00:34

    宇树科技 G1人形机器人,拉动一辆重达1.4吨的汽车

    00:21

    Cloudera 调查发现,96% 的企业已将 AI 集成到核心业务流程中,这表明 AI 已从竞争优势转变为强制性实践

    02:05

    投资者反对马斯克 1 万亿美元薪酬方案,要求重组特斯拉董事会

    01:18

    技术热点

    大型网站的 HTTPS 实践(三):基于协议和配置的优化

    ubuntu下右键菜单添加新建word、excel文档等快捷方式

    Sublime Text 简明教程

    用户定义SQL Server函数的描述

    怎么在windows 7开始菜单中添加下载选项?

    SQL Server 2016将有哪些功能改进?

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。