javascript成神之路(2):深入理解原型以及原型链的重要性

简介:

原型

一、什么是原型

每个函数对象都有一个prototype属性,这个属性这个属性是一个指针,指向一个对象。当函数作为构造函数使用时这个对象会成为调用该构造函数而创建的实例的原型,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。是不是感觉一脸懵逼呢?我们先看看下面一个例子: 

function Sanpang(val) { this.valueA = val; } Sanpang.prototype.sayHello = function () { console.log(this.valueA); } var f1 = new Sanpang(1); var f2 = new SanpangF(2); // 由F函数生成的实例都会包含sayA方法 f1.sayHello(); f2.sayHello();

就是说,构造函数生成的实例会有一组共享的属性和方法,这些属性和方法在构造函数的原型对象里。看到这里大家应该稍微有点眉目了吧。

二、原型的使用方式

1.在赋值原型prototype的时候使用function立即执行的表达式来赋值,示例如下:

A.prototype = function () { } ();

这种方法的好处就是可以封装私有的function,通过return的形式暴露出简单的使用名称,以达到public/private的效果。

A.prototype = function () { addF = function (x, y) { return x + y; }, subtractF = function (x, y) { return x - y; } return { add: addF, subtract: subtractF } } ();

调用的时候我们用new A.add(1,2),这样我们就计算出结果了。

2.分开设置每个原型的属性,示例如下:

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

第一种方式就是一次性设置了原型对象,所以有一定的弊端。这样我们就声明了一个B对象,构造函数里会初始化一个小数位数的属性decimalDigits,然后通过原型属性设置2个function,分别是add(x,y)和subtract(x,y),当然你也可以使用前面提到的2种方式的任何一种,我们的主要目的是看如何将B对象设置到真正的C的原型上。

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

当上B创建成功以后我们开始设置C

var C = function () { this.tax = 5; //每一个实例都有这个tax属性 }; C.prototype = new B();

这样的话C的原型是指向到B的一个实例上,目的是让C集成它的add(x,y)和subtract(x,y)这2个function,由于它的原型是B的一个实例,所以不管你创建多少个C对象实例,他们的原型指向的都是同一个实例。这样我们就可以运行下面的代码:

var c = new C(); alert(c.add(1, 1)); //B 里声明的decimalDigits属性,在 C里是可以访问到的 alert(c.decimalDigits); //同样是可以访问到的

如果我不想让C访问B的构造函数里声明的属性值,那该杂么做?

var C = function () { this.tax= 5; }; C.prototype = B.prototype;

这样通过将B的原型赋给C的原型,这样你在C的实例上就访问不到那个decimalDigits值了,如果你访问下面的代码将会报错。

var c = new C(); alert(c.add(1, 1)); alert(c.decimalDigits);

3.重写原型:

当我们使用第三方javascript类库的时候,往往有时候他们定义的原型方法是不能满足我们的需要,但是又离不开这个类库,所以这时候我们就需要重写他们的原型中的一个或者多个属性或function,我们可以通过继续声明的同样的add代码的形式来达到覆盖重写前面的add功能,代码如下:

覆盖前面C的add() function C.prototype.add = function (x, y) { return x + y + this.tax; }; var c = new C(); alert(c.add(2, 2));

我们现在调用的结果就比原来多出了一个tax的值,但是有一点需要注意:那就是重写的代码需要放在最后,这样才能覆盖前面的代码。

原型链

原型链,是JS实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。示例如下:

function F() { this.value = 1; } F.prototype = { method: function() {} }; function B() {} B.prototype = new F(); B.prototype.foo = 'Hello World'; // 修正B.prototype.constructor为B本身 B.prototype.constructor = B; var test = new B() // 创建B的一个新实例 // 原型链 t => [B的实例] B.prototype [F的实例] { foo: 'Hello World' } F.prototype {method: ...}; Object.prototype {toString:等等};

以上的例子,t 对象从 B.prototype 和 F.prototype 继承下来;因此,它能访问 F 的原型方法 method。同时,它也能够访问那个定义在原型上的 F 实例属性 value。需要注意的是 new B() 不会创造出一个新的 F 实例,而是重复使用它原型上的那个实例;因此,所有的 B 实例都会共享相同的 value 属性。

总结

  • 原型和原型链是 JS 实现继承的一种模型。
  • 原型链是靠 _proto _ 形成的,而不是 prototype。
  • 所有的原型对象都有 constructor 属性,该属性对应创建所有指向该原型的实例构造函数。
  • 函数对象和原型对象通过 prototype 和 constructor 属性进行相互关联。

原文发布时间:2018年01月07日

作者:技术金三胖

本文来源:开源中国  如需转载请联系原作者

目录
相关文章
|
数据可视化
R语言弹性网络Elastic Net正则化惩罚回归模型交叉验证可视化
R语言弹性网络Elastic Net正则化惩罚回归模型交叉验证可视化
|
4月前
|
数据采集 人工智能 安全
开源赋能双碳:MyEMS 能源管理系统的架构与实践价值
在全球碳中和趋势与“双碳”目标推动下,能源管理趋向精细化与智能化。MyEMS是一款基于Python开发的开源能源管理系统,具备灵活适配、功能全面的优势,覆盖工厂、建筑、数据中心等多元场景。系统支持能源数据采集、分析、可视化及设备管理、故障诊断、AI优化控制等功能,提供“监测-分析-优化”闭环解决方案。遵循“国家+省级+接入端”三级架构,MyEMS在重点用能单位能耗监测中发挥关键作用,助力实现能源效率提升与政策合规。开源模式降低了技术门槛,推动“双碳”目标落地。
190 0
|
4月前
|
数据采集 存储 算法
MyEMS 开源能源管理系统:基于 4G 无线传感网络的能源数据闭环管理方案
MyEMS 是开源能源管理领域的标杆解决方案,采用 Python、Django 与 React 技术栈,具备模块化架构与跨平台兼容性。系统涵盖能源数据治理、设备管理、工单流转与智能控制四大核心功能,结合高精度 4G 无线计量仪表,实现高效数据采集与边缘计算。方案部署灵活、安全性高,助力企业实现能源数字化与碳减排目标。
145 0
|
6月前
|
存储 安全 大数据
网安工程师必看!AiPy解决fscan扫描数据整理难题—多种信息快速分拣+Excel结构化存储方案
作为一名安全测试工程师,分析fscan扫描结果曾是繁琐的手动活:从海量日志中提取开放端口、漏洞信息和主机数据,耗时又易错。但现在,借助AiPy开发的GUI解析工具,只需喝杯奶茶的时间,即可将[PORT]、[SERVICE]、[VULN]、[HOST]等关键信息智能分类,并生成三份清晰的Excel报表。告别手动整理,大幅提升效率!在安全行业,工具党正碾压手动党。掌握AiPy,把时间留给真正的攻防实战!官网链接:https://www.aipyaipy.com,解锁更多用法!
|
SQL 存储 数据库
SQL语句是否都需要解析及其相关技巧与方法
在数据库管理系统中,SQL(Structured Query Language)语句作为与数据库交互的桥梁,其执行过程往往涉及到一个或多个解析阶段
|
9月前
|
传感器 人工智能 数据可视化
数智入海,GIS赋能智慧海洋
随着科技发展,各国积极推进海洋数字化建设,建立全球海洋观测网络,获取实时数据并挖掘价值。我国从“十四五”规划到二十大报告强调海洋强国战略,利用地理空间信息技术和物联网整合监测数据,提供智能管理与决策支持,实现海洋环境的可视化三维场景、实时监测、环境保护、灾害预警及专题图件服务,推动海洋经济高质量发展。
基于kalman滤波的UAV三维轨迹跟踪算法matlab仿真
本文介绍了一种使用卡尔曼滤波(Kalman Filter)对无人飞行器(UAV)在三维空间中的运动轨迹进行预测和估计的方法。该方法通过状态预测和观测更新两个关键步骤,实时估计UAV的位置和速度,进而生成三维轨迹。在MATLAB 2022a环境下验证了算法的有效性(参见附图)。核心程序实现了状态估计和误差协方差矩阵的更新,并通过调整参数优化滤波效果。该算法有助于提高轨迹跟踪精度和稳定性,适用于多种应用场景,例如航拍和物流运输等领域。
956 12
|
关系型数据库 数据库连接 分布式数据库
PolarDB操作报错合集之数据库访问量低时,可以正常连接数据库,访问量高了所有用户都连接不了数据库,为什么
PolarDB是阿里云推出的一种云原生数据库服务,专为云设计,提供兼容MySQL、PostgreSQL的高性能、低成本、弹性可扩展的数据库解决方案,可以有效地管理和优化PolarDB实例,确保数据库服务的稳定、高效运行。以下是使用PolarDB产品的一些建议和最佳实践合集。
365 0
|
SQL HIVE
Hive【Hive学习大纲】【数据仓库+简介+工作原理】【自学阶段整理的xmind思维导图分享】【点击可放大看高清】
【4月更文挑战第6天】Hive【Hive学习大纲】【数据仓库+简介+工作原理】【自学阶段整理的xmind思维导图分享】【点击可放大看高清】
417 0
|
云安全 存储 运维
首次全面解析云原生成熟度模型:解决企业「诊断难、规划难、选型难」问题
从“上云”到“云上”原生,云原生提供了最优用云路径,云原生的技术价值已被广泛认可。当前行业用户全面转型云原生已是大势所趋,用户侧云原生平台建设和应用云原生化改造进程正在加速。
2857 102
首次全面解析云原生成熟度模型:解决企业「诊断难、规划难、选型难」问题