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日

作者:技术金三胖

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

目录
相关文章
|
1月前
|
监控 安全 物联网
化工厂人员定位技术从系统架构到核心功能详解(一)
化工厂人员定位技术以UWB高精度定位为核心,融合物联网与大数据,构建五层系统架构,实现人员实时定位、电子围栏预警、一键SOS报警及应急联动,提升高危区域安全管控与应急响应能力。如果您想进一步了解定位的案例,欢迎关注、评论留言~也可搜索lbs智能定位。
|
6月前
|
数据采集 人工智能 安全
开源赋能双碳:MyEMS 能源管理系统的架构与实践价值
在全球碳中和趋势与“双碳”目标推动下,能源管理趋向精细化与智能化。MyEMS是一款基于Python开发的开源能源管理系统,具备灵活适配、功能全面的优势,覆盖工厂、建筑、数据中心等多元场景。系统支持能源数据采集、分析、可视化及设备管理、故障诊断、AI优化控制等功能,提供“监测-分析-优化”闭环解决方案。遵循“国家+省级+接入端”三级架构,MyEMS在重点用能单位能耗监测中发挥关键作用,助力实现能源效率提升与政策合规。开源模式降低了技术门槛,推动“双碳”目标落地。
242 0
|
4月前
|
机器学习/深度学习 监控 安全
基于YOLOv8的跨越围栏/翻墙行为识别项目|开箱即用全流程源码
本项目基于YOLOv8目标检测模型和PyQt5图形界面工具,成功实现了翻越攀爬围栏和翻墙行为的智能检测系统。通过集成YOLOv8的高效目标检测能力和PyQt5的易用界面,本系统能够准确识别不同场景中的翻越行为,并提供多种输入方式(图片、视频、文件夹、摄像头)进行实时检测,满足多种应用需求。
|
4月前
|
存储 安全 固态存储
基于C#实现的支持文件传输的Socket聊天室
基于C#实现的支持文件传输的Socket聊天室
318 5
|
4月前
|
JavaScript Java 关系型数据库
2025版基于springboot的企业办公用品采购管理系统
本系统旨在优化企业办公用品采购流程,通过自动化、标准化管理,提升采购效率,降低运营成本。结合Spring Boot、Vue、Java与MySQL技术,实现需求申请、审批、采购、入库全流程数字化,助力企业实现高效、智能的采购管理,增强市场竞争力。
|
10月前
|
运维 jenkins 测试技术
Websoft9 面板是干什么的?
Websoft9 是一款专注于 Web 应用部署与管理的服务器面板工具,通过自动化脚本和图形化界面简化主流开源软件(如 WordPress、GitLab 等)的安装、配置和管理。它支持一键部署、集中管理和基础运维功能,降低技术门槛,适合个人站长、开发者及中小企业使用。提供丰富的应用市场、跨平台兼容性和完善的文档,帮助企业快速实现业务上线并减少运维成本。
326 1
Websoft9 面板是干什么的?
|
11月前
|
传感器 人工智能 数据可视化
数智入海,GIS赋能智慧海洋
随着科技发展,各国积极推进海洋数字化建设,建立全球海洋观测网络,获取实时数据并挖掘价值。我国从“十四五”规划到二十大报告强调海洋强国战略,利用地理空间信息技术和物联网整合监测数据,提供智能管理与决策支持,实现海洋环境的可视化三维场景、实时监测、环境保护、灾害预警及专题图件服务,推动海洋经济高质量发展。
|
存储 JSON 测试技术
Python中最值得学习的第三方JSON库
Python中最值得学习的第三方JSON库
471 0
|
程序员 计算机视觉
程序员的“防御性编程”
最近都在聊程序员要做好“防御性编程”,"防御性编程"的概念从之前的“保护程序”一下子变成了现在的“保护程序员”,一字之差,千差万别。
程序员的“防御性编程”

热门文章

最新文章