热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javascript的继续你相识若干?

什么是继续?大多数人运用继续不外乎是为了取得这两点优点,代码的笼统和代码的复用。代码的笼统就不用说了,交通东西和汽车这类的例子不可胜数,在传统的OO语言中(比如Java),代码的笼

什么是继续?

大多数人运用继续不外乎是为了取得这两点优点,代码的笼统和代码的复用。

代码的笼统就不用说了,交通东西和汽车这类的例子不可胜数,在传统的OO语言中(比如Java),代码的笼统更多的是运用接口(interface)来完成,而运用继续更多地是为了代码的复用(虽然如今强调运用组合而不是运用继续)。

怎样复用的?打个比如,class A 继续了 class B,class A便具有了class B 的public 和 protected范例的变量和要领,用最简朴的要领去想,就是 class B 将 这些属性和要领直接copy给class A,如许便完成了继续。

因而我们能够如许说,继续实际上是一品种与类之间的copy行动。

Javascript中的继续

在Javascript中没有类的观点,只要对象。虽然如今人们常常运用class关键字,这让Javascript看起来似乎是具有了”类”,可外表看到的不一定是实质,class只是一块糖,嚼碎了才晓得内里实在照样原型链那一套。因而,Javascript中的继续只是对象与对象之间的继续。反观继续的实质,继续就是让子类具有父类的一些属性和要领,那末在Javascript中就是让一个对象具有另一个对象的属性和要领。

所以,这给我了我们一条非常清楚的思绪,Javascript中怎样完成继续?只需让一个对象具有另一个对象的属性和要领,这就完成了。

应用Mixin

既然让一个对象具有另一个对象的属性和要领,起首想到的就是应用Mixin的粗犷体式格局,直接将对象的属性和要领强迫copy到另一个对象。

就像如许

function mixin(subObj, parentObj) {
for (var prop in parentObj) {
if (!(prop in subObj)) {
subObj[prop] = parentObj[prop]
}
}
}

固然也能够用ES6中的更文雅的Object.assign。

这段代码就完成了最简朴的从一个对象复制属性和要领到另一个对象。然则这类要领有一个缺点,假如父对象的属性是援用范例,比如一个对象或许数组,那末修正子对象的时刻必将会对父对象也形成修正,这明显不可接收。一种主意是采纳深度克隆,然则又可能会有轮回援用的题目。

所以,这类继续体式格局,比较合适对简朴对象的拓展,不太合适更庞杂的继续。

应用原型链

起首来讲一下什么是原型,原型在Javascript中,实在就是某个对象的一个属性。只不过这个属性很特别,关于外界平常是不可见(在chrome中能够经由过程__proto__猎取),我们平常把它叫作[[Prototype]]。这里和函数的prototype属性很相似但倒是两个东西,后面会提到。

那末什么是原型链呢,望文生义就像如许:

obj1.[[Prototype]] ===> obj2.[[Prototype]] ===> obj3.[[Prototype]]…. ===> Object.prototype

某一对象的原型属性中保存着另一个对象,以此类推,彷佛链子一样串起来。

链的尽头是Object.prototype对象,因而Object.prototype没有原型。当我们构建一个对象,这个对象的默许的原型就是Object.prototype

在chrome中考证一下:

var a = {}
Object.prototype === a.__proto__ // true

那末我们怎样用原型链完成继续呢?这要归功于Javascript中的托付机制。

当我们猎取一个对象的某个属性时,比如a.b,会默许挪用一个内置的[[Get]]要领,这个[[Get]]要领的算法就是:

在当前对象里查找,找不到则托付给当前对象的[[Prototype]],再找不到则托付给[[Prototype]]的[[Prototype]],直到Object.prototype中也没找到,则返回undefined。

因而,我们想让对象a具有对象b的属性和要领,即对象a继续对象b,只需要把b赋值给a的[[Prototype]],应用属性查找的托付机制,完成了a也”具有”了b的属性和要领,而且当a中有和b中的同名属性时,因为”屏障作用”,只要a中的属性会被优先猎取到,完成了override,看起来相称圆满。

new 和 “组织函数”

前面提到,[[Prototype]]是个内置隐蔽属性,虽然在chrome能够经由过程__proto__接见,然则其设想本意是不可被读取和修正的,那末我们怎样应用原型链来竖立继续关联?

Javascript供应了new关键字。

一般,在相似Java如许的OO语言中,new被用来实例化一个类,然则在Javascript中,new仅仅是一个函数挪用的体式格局!

Javascript中的函数也很新鲜,每个函数都有一个默许的prototype属性,这个差别于对象的[[Prototype]]属性,函数的prototype是有意暴露出来的,而且这个属性还不为空,另有prototype另有另一个属性叫constructor,这个constructor居然又援用回来了这个函数自身!因而我们看到的结果是如许的:

《Javascript的继续你相识若干?》

用new来挪用函数有什么差别的呢?new实在做了三件事:

  • 建立一个新对象
  • 将这个新对象的[[Prototype]]衔接到挪用函数的prototype上
  • 绑定挪用函数的this并挪用

用代码来示意就是:

function New(fn) {
var tmp = {}
tmp.__proto__ = fn.prototype
fn.call(tmp)
return tmp
}

能够看到,new帮我们把对象的[[Prototype]]衔接到了函数的prototype上。

到这儿,思绪就清楚了,怎样让对象a和对象b的[[Prototype]]相连完成a继续b?

只需把a的”组织函数”的[[Prototype]]衔接到b就好了。

来完成一下:

function A() {}
var b = {
show: function() {
console.log('这是来自b的要领')
}
}
A.prototype = b
// 这里修复了本来的 constructor
A.prototype.cOnstructor= A
var a = new A()
a.show() // 这是来自b的要领

更简朴的Object.create

ES5中供应的Object.create更简朴粗犷,能够直接建立一个对象并将这个对象的[[Prototype]]指向传入的对象

var b = {c: 1}
var a = Object.create(b)
console.log(a.c) // 1

模仿类继续

在Javascript中没有类的观点,虽然从ES6最先具有了class关键字,但其背地仍然是原型链作支持,所以这里照样用最实质的原型来模仿”类”的继续。这才是Javascript的本来面目!

/**
* 完成 A 继续 B
*/
function B(b) {
this.b = b
}
function A(a, b) {
// 挪用B并绑定this
B.call(this, b)
this.a = a
}
A.prototype = Object.assign({}, B.prototype)
A.prototype.cOnstructor= A
var c = new A(1, 2)
console.log(c.a) // 1
// c 具有了只要B的实例才具有的 b 属性
console.log(c.b) // 2

总结

简朴来讲,继续等于copy和复用,Javascript的继续实在就是应用原型链的查找和托付来完成属性和要领的复用,new关键字和”组织函数”只是衔接原型链的东西,如许的东西另有Object.create。


推荐阅读
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • 本文介绍了如何在iOS应用中自定义导航栏按钮,包括使用普通按钮和图片生成导航条专用按钮的方法。同时,探讨了在不同版本的iOS系统中实现多按钮布局的技术方案。 ... [详细]
  • JavaScript 中创建对象的多种方法
    本文详细介绍了 JavaScript 中创建对象的几种常见方式,包括对象字面量、构造函数和 Object.create 方法,并提供了示例代码和属性描述符的解释。 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 本文介绍了如何在 C# 和 XNA 框架中实现一个自定义的 3x3 矩阵类(MMatrix33),旨在深入理解矩阵运算及其应用场景。该类参考了 AS3 Starling 和其他相关资源,以确保算法的准确性和高效性。 ... [详细]
  • 探讨ChatGPT在法律和版权方面的潜在风险及影响,分析其作为内容创造工具的合法性和合规性。 ... [详细]
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
  • 本文介绍了如何在多线程环境中实现异步任务的事务控制,确保任务执行的一致性和可靠性。通过使用计数器和异常标记字段,系统能够准确判断所有异步线程的执行结果,并根据结果决定是否回滚或提交事务。 ... [详细]
  • 历经三十年的开发,Mathematica 已成为技术计算领域的标杆,为全球的技术创新者、教育工作者、学生及其他用户提供了一个领先的计算平台。最新版本 Mathematica 12.3.1 增加了多项核心语言、数学计算、可视化和图形处理的新功能。 ... [详细]
  • 本文详细介绍如何使用 HTML5 和 JavaScript 实现一个交互式的画板功能。通过具体代码示例,帮助读者理解 Canvas API 的基本用法及其在绘图应用中的实际应用。 ... [详细]
  • 本文将详细介绍多个流行的 Android 视频处理开源框架,包括 ijkplayer、FFmpeg、Vitamio、ExoPlayer 等。每个框架都有其独特的优势和应用场景,帮助开发者更高效地进行视频处理和播放。 ... [详细]
  • 本文回顾了2017年的转型和2018年的收获,分享了几家知名互联网公司提供的工作机会及面试体验。 ... [详细]
  • 版本控制工具——Git常用操作(下)
    本文由云+社区发表作者:工程师小熊摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码、使用分支、出现代码冲突的解决办法、紧急保存现场和恢复 ... [详细]
author-avatar
xzcxzfvxvc
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有