前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >javascript设计模式五:原型模式

javascript设计模式五:原型模式

作者头像
前端_AWhile
发布于 2019-08-29 07:11:47
发布于 2019-08-29 07:11:47
30900
代码可运行
举报
文章被收录于专栏:前端一会前端一会
运行总次数:0
代码可运行

javascript语言中,原型与原型链是一个非常重要的概念,因为它们是javascript语言得以成立的根本。因为javascript是基于原型的面向对象编程语言,这有别于基于类的javapython等面向对象编程语言。虽然javscript现在也有了class,但它骨子里还是个基于原型的语法糖罢了。所以在使用javascript时,始终要记清基于原型,基于原型,基于原型。

在说原型和原型链前,先了解js中它们各自的表达单词:原型 prototype原型链 __proto__,目前只有在chrome和firefox浏览器中可以看到原型链暴露出来,其他浏览器暂时不可见。

javascript中的数据类型主要有undefinedNullNumberStringBooleanSymbolobject。其中除了undefined外,一切都是对象。

那么这些对象既然都是基于原型出来的,那javascript中肯定就有一个根对象(根原型对象),它就是Object.prototype,在平时通过对象字面量var obj = {}new Object()创建新对象时,都是从Object.prototype这克隆来的,而由于Object.prototype对象本身拥有toString()hasOwnProperty()等方法,所以从其克隆而出的新对象也天然拥有这些称为"原型方法"的方法。这些"原型方法"不是新创建的对象所具有的,它们是原型对象所具有,是新建对象可以通过原型链(__proto__)直接访问到的。是不是跟继承很像?发散下思维,通过原型克隆是不是可以实现类中的继承?

来看下通过对象字面量{}新建对象的原型方法:

在知道了js中所有对象的原型对象是Object.prototype后,可能有的人会有疑问,这个原型对象难道就是js世界里的终点了么?它又是从何而来呢?显然不是,Object.prototype的原型就是null,就是虚无。这里扯开来,我的理解它有点类似道德经。

道德经有云:道生一,一生二,二生三,三生万物。

js世界中的null类似道,nullObject.prototypeObject.prototype生各种对象,各种对象生万物。以下给出我珍藏已久的js万物图帮助理解记忆:

在es5前,生成对象的原型只能达到Object.prototype,但es5出来后,js中新出个Object.create()方法可以创建以任意对象为原型的对象了,换言之,最高我们可以创建以null为原型对象的对象了Object.create(null),其用处广泛,例如在Vue和Vuex的源码中,作者都使用了Object.create(null)来初始化一个新对象,而非使用{}。因为通过前者创建的对象没有任何属性和方法,非常干净,我们可以在创建出来的对象上自定义任何属性方法而不必担心与原型链上的方法冲突。

虽然Object.create()非常好用,但是并非所有浏览器版本均支持,所以在使用该方法时,可以通过以下方法兼容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object.create = Object.create || function(obj){
    var F = function(){}
    F.prototype = obj;  //将构造函数的原型手动指向需要克隆的原型对象
    return new F();     //通过new构造函数创建对象,此时新建的对象就继承自构造器的原型对象
                        //此时可以查看返回值的__proto__属性里继承来的属性方法
}

这里需要再澄清一个概念,对于一直在讨论的"对象的原型",就javascript的真正实现来说,其实并不能说对象有原型,而只能说对象的构造器有原型,对于"对象把请求委托给自己的原型"这句话,更好的说法应是"对象把请求委托给自己的构造器的原型"。

那么对象如何顺利的把请求委托给自己构造器的原型呢?就要提到上文说到的隐藏属性原型链了__proto__,某个对象的__proto__默认会指向其构造器的原型上,伪代码表示为new F().__proto__ -> F.prototype,即构造器new出来的对象的__proto__结果指向构造器的prototype:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var F = function(){}
var f = new F()
console.log(f.__protot__ === F.prototype);  //true

总结一下,在js中,对象可以通过原型克隆来实现获取/继承原型对象的属性和方法,大多数情况下原型对象都是Object.prototype,但有必要时,既可以通过Object.create()方法实现以任意对象为原型的克隆操作,也可以通过修改构造器的prototype指向来借用其他对象的属性方法,这种思想其实是非常风骚的,但也非常危险,用时自己斟酌吧。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端小二 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
笨办法理解原型链
关于原型链的文章之前写了一篇 https://my.oschina.net/lilugirl2005/blog/1825752
lilugirl
2019/05/28
2990
笨办法理解原型链
彻底搞懂JS原型与原型链
说到JavaScript的原型和原型链,相关文章已有不少,但是大都晦涩难懂。本文将换一个角度出发,先理解原型和原型链是什么,有什么作用,再去分析那些令人头疼的关系。
hellocoder2029
2022/10/17
3.1K1
原型链
每个实例对象(object)都有一个私有属性(__proto__)指向其构造函数的原型对象(prototype)。该原型对象也有自己的原型对象,层层向上直到一个对象的原型对象为null。根据定义null没有原型,并作为原型链的最后一个环节。
用户3258338
2020/03/12
4430
设计模式(7)[JS版]-JavaScript设计模式之原型模式如何实现???
原型模式(prototype)是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象。 原型模式不单是一种设计模式,也被称为一种编程泛型。 从设计模式的角度讲,原型模式是用于创建对象的一种模式。我们不再关心对象的具体类型,而是找到一个对象,然后通过克隆来创建一个一模一样的对象。在其他语言很少使用原型模式,但是JavaScript作为原型语言,在构造新对象及其原型时会使用该模式。
AlbertYang
2020/09/08
1.3K0
设计模式(7)[JS版]-JavaScript设计模式之原型模式如何实现???
JavaScript学习总结(四)——this、原型链、javascript面向对象
根据题目要求,对给定的文章进行摘要总结。
张果
2018/01/04
1.5K0
JavaScript学习总结(四)——this、原型链、javascript面向对象
Javascript之其实我觉得原型链没有难的那么夸张!
  原型链、闭包、事件循环等,可以说是js中比较复杂的知识了,复杂的不是因为它的概念,而是因为它们本身都涉及到很多的知识体系。所以很难串联起来,有一个完整的思路。我最近想把js中有点意思的知识都总结整理一下,虽然逃不开一些一模一样的内容,但是自己造一下轮子,按照自己的思路。也别有一番味道。
zaking
2020/08/19
7560
JavaScript原型链档案
事实上JavaScript一直以来都是基于对象和原型的,除了Number、String、Boolean等基本数据类型之外,JavaScript中的一切都是对象。ES6中新增的class、constructor、static、extends、super等关键字都是基于对象和原型的语法糖。
gojam
2019/05/14
3760
Javascript 原型链
每个实例对象(object)都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(__proto__),层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
超级大帅比
2021/09/06
5850
JS 设计模式之原型模式(创建型)
原型模式不仅是一种设计模式,它还是一种编程范式(programming paradigm),是 JavaScript 面向对象系统实现的根基。
Leophen
2021/08/06
5970
JS 设计模式之原型模式(创建型)
JavaScript原型与继承
对于使用过基于类的语言 (如 Java 或 C++) 的开发人员来说,JavaScript 有点令人困惑,因为它是动态的,并且本身不提供一个 class 实现。(在 ES2015/ES6 中引入了 class 关键字,但那只是语法糖,JavaScript 仍然是基于原型的)。
用户1428723
2020/08/06
5510
JavaScript继承和原型链
JS在加载构造函数时,会在内存中生成一个对象,这个对象称为函数的原型对象(prototype)。
前端航航
2022/11/11
4610
关于javascript的原型和原型链,看我就够了(一)
关于js的原型和原型链,有人觉得这是很头疼的一块知识点,其实不然,它很基础,不信,往下看 要了解原型和原型链,我们得先从对象说起
陌上寒
2019/04/02
3660
关于javascript的原型和原型链,看我就够了(一)
[JS必知必会]原型链这么看好像并不难
上面一段代码,声明第一个函数foo的时候,它就会带一个foo.prototype的属性,这个属性是一个对象属性,用new foo();构造器的方式构造一个新的对象obj。这时候这个obj的原型会指向foo的prototype属性。 对于这个foo函数的原型也会指向Object.prototype,这个Object.prototype也是有原型的,它的原型指向null。
coder_koala
2019/07/30
4760
[JS必知必会]原型链这么看好像并不难
JS 继承
用过 React的读者知道,经常用 extends继承 React.Component:
grain先森
2019/03/28
3K0
JS 继承
深入JavaScript原型链污染
相比其他语言(如Java、python等传统OOP语言),JavaScript的机制和类完全不同。
raye
2024/02/04
2301
深度剖析前端JavaScript中的原型(JS的对象原型)
JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。
Tz一号
2020/09/10
1.2K0
【THE LAST TIME】一文吃透所有JS原型相关知识点
首先我想说,【THE LAST TIME】系列的的内容,向来都是包括但不限于标题的范围。
Nealyang
2019/11/04
1.1K0
关于javascript的原型和原型链,看我就够了(三)
原型对象有一个constructor属性,指向该原型对象对应的构造函数 foo 为什么有 constructor 属性?那是因为 foo 是 Foo 的实例。 那 Foo.prototype 为什么有 constructor 属性??同理, Foo.prototype Foo 的实例。 也就是在 Foo 创建的时候,创建了一个它的实例对象并赋值给它的 prototype
陌上寒
2019/04/02
5160
关于javascript的原型和原型链,看我就够了(三)
JS原型链与继承别再被问倒了
继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实现继承则继承实际的方法.由于js中方法没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支持实现继承,而且其 实现继承 主要是依靠原型链来实现的.
全栈程序员站长
2021/06/10
6330
一站搞定原型链:深入理解JavaScript的继承机制
JavaScript 的原型链(prototype chain)是理解 JavaScript 对象和继承机制的关键。它是通过对象的原型(prototype)属性实现的,用于实现对象属性和方法的共享和继承。以下是对 JavaScript 原型链的详细介绍,这一篇文章将会通过理论与demo相结合的方式,力争一文概括原型、对象、原型链以及基于原型链实现JavaScript的继承机制的所有方面,帮助您一站式搞定原型链。
watermelo37
2025/01/22
940
一站搞定原型链:深入理解JavaScript的继承机制
相关推荐
笨办法理解原型链
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验