JavaScript之原型链与原型链继承
原型链
定义:每个实例对象(object)都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(__proto__),层层向上直到一个对象的原型对象为 null
。
prototype:(原型对象)函数独有的属性
constructor:(构造函数)每个函数都有一个原型对象,该原型对象有一个 constructor 属性,指向创建对象的函数本身。
__proto__:(原型)对象的私有属性(在 JavaScript 中一切皆对象)
原型链图解:
继承方式(es5):
方式1:基于原型链继承
弊端:当原型中存在引用类型的值时,实例能够修改这个引用类型的值(不够安全)
// 新建父类 Base
function Base() {
this.name = 'tomni'
// jobInfo为一个引用类型
this.jobInfo = {
jobName: 'job1',
price: 1000
}
} // 在原型上添加 getName 方法
Base.prototype.getName = function() {
return this.name
} // 创建子类
function Sub() {
this.age = 18
}
const newBase = new Base()
/**
* 原型链继承
* 1. 将 Sub 的原型对象指向 newBase
* 2. 将 Sub 原型对象的构造函数执行本身(Sub)
*/
Sub.prototype = newBase
Sub.prototype.constructor = Sub /** *** 原型链继承的问题 *** */
const newSub = new Sub()
const newSub2 = new Sub()
// 修改实例 newSub.jobInfo 中的 jobName
newSub.jobInfo.jobName = 'job22'
// 打印 newSub2.jobInfo.jobName
// 会发现 newSub2.jobInfo 这个对象也被修改了
console.log(newSub2.jobInfo) // -> job22
方式2:更改函数 this 指向实现继承
弊端:无法继承父对象中的原型对象(prototype)中的属性和方法,每次实例化都需要执行一遍父对象,性能欠佳
// 新建父类 Base
function Base() {
this.name = 'tomni'
// jobInfo为一个引用类型
this.jobInfo = {
jobName: 'job1',
price: 1000
}
} // 在原型上添加 getName 方法
Base.prototype.getName = function() {
return this.name
} // 创建子类
function Sub() {
// 使用当前上下文 this 执行 Base 函数(每次对 Sub 实例化都需要执行)
Base.call(this)
this.age = 18
} const newSub = new Sub() // 改变this指向的方式实现继承,无法继承其原型对象(prototype)中的方法与属性
// Uncaught TypeError: newSub.getName is not a function
console.log(newSub.getName())
方式3:组合式继承
弊端:每次创建子实例,父对象原型对象中的构造函数会被执行两次
// 新建父类 Base
function Base() {
this.name = 'tomni'
// jobInfo为一个引用类型
this.jobInfo = {
jobName: 'job1',
price: 1000
} // 会执行两次(因为创建 Sub 实例的过程中,Base.prototype.constructor 被执行了两次)
console.log('constructor')
} // 在原型上添加 getName 方法
Base.prototype.getName = function() {
return this.name
} // 创建子类
function Sub() {
// 修改 this 指向实现继承
Base.call(this)
this.age = 18
} // 原型链继承
Sub.prototype = new Base()
Sub.prototype.constructor = Sub const newSub = new Sub()
const newSub2 = new Sub() // 父对象中 引用类型 被影响的问题得以解决
newSub.jobInfo.jobName = '1111'
console.log(newSub2.jobInfo.jobName) // 无法继承 父对象原型对象中的属性和方法 问题得以解决
console.log(newSub.getName()) // -> tomni
JavaScript之原型链与原型链继承的更多相关文章
- 《JAVASCRIPT高级程序设计》根植于原型链的继承
继承是面向对象的语言中,一个最为津津乐道并乐此不疲的话题之一.JAVASCRIPT中的继承,主要是依靠原型链来实现的.上一篇文章介绍过,JAVASCRIPT中,每一个对象都有一个prototype属性 ...
- Javascript原型链和原型继承
哇好久都没有写随笔啦,整个人都慵懒啦. 为了不让大家忘记我,把以前写过的一些慢慢发出来. 在JS 中, 有两条链子,作用域链 和 原型链. 作用域链相对容易理解,两点 - 函数限定变量作用域,就是说, ...
- javascript中的对象,原型,原型链和面向对象
一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...
- 【javascript基础】4、原型与原型链
前言 荒废了好几天,在宿舍闷了几天了,一直想着回家放松,什么也没搞,论文就让老师催吧.不过,闲的没事干的感觉真是不好,还是看看书,写写博客吧,今天和大家说说函数的原型. 原型是什么 第一次看到这个的时 ...
- JavaScript探秘:强大的原型和原型链
// foo 变量是上例中的 for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i); } } JavaScript 不包括传统 ...
- javascript中的构造函数和原型及原型链
纯属个人理解,有错误的地方希望大牛指出,以免误人子弟 1.构造函数: 构造函数的作用 : 初始化由new创建出来的对象 new 的作用: 创建对象(空对象) new 后面跟的是函数调用,使用ne ...
- JS原型,原型链,类,继承,class,extends,由浅到深
一.构造函数和原型 1.构造函数.静态成员和实例成员 在ES6之前,通常用一种称为构造函数的特殊函数来定义对象及其特征,然后用构造函数来创建对象.像其他面向对象的语言一样,将抽象后的属性和方法封装到对 ...
- [js高手之路]一步步图解javascript的原型(prototype)对象,原型链
我们接着上文继续,我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉. function CreateObj(uName) { this ...
- js 原型,原型链,原型链继承浅析
对于网上的关于原型,原型链和原型链继承的晦涩语言说明就不累赘了,复制粘贴过来再解释一遍怕自己也整蒙了,本人最怕空气突然安静,四目对视,大眼对小眼,一脸懵逼. 我们先看下面
- 【javascript】对原型对象、原型链的理解
原型对象,原型链这些知识属于基础类知识.但是平时开发过程中也很少用到. 看网上的意思,原型链用于es5开发场景下的继承.es6有了类语法糖之后,就自带继承了. 通过理解,个人画了一张原型链解构的关系图 ...
随机推荐
- 【LeetCode】438. Find All Anagrams in a String 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 滑动窗口 双指针 日期 题目地址:https://l ...
- 【LeetCode】395. Longest Substring with At Least K Repeating Characters 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/longest- ...
- 【LeetCode】609. Find Duplicate File in System 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【LeetCode】686. Repeated String Match 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 实战!Spring Boot 整合 阿里开源中间件 Canal 实现数据增量同步!
大家好,我是不才陈某~ 数据同步一直是一个令人头疼的问题.在业务量小,场景不多,数据量不大的情况下我们可能会选择在项目中直接写一些定时任务手动处理数据,例如从多个表将数据查出来,再汇总处理,再插入到相 ...
- 第四十个知识点 一般来说SPA和DPA的区别是什么
第四十个知识点 一般来说SPA和DPA的区别是什么 原文地址:http://bristolcrypto.blogspot.com/2015/07/52-things-number-40-what-is ...
- 新手入门typeScript
强类型与弱类型(类型安全) 强类型不允许随意的隐士类型转换,而弱类型是允许的 变量类型允许随时改变的特点,不是强弱类型的差异 静态类型与动态类型(类型检查) 静态类型:一个变量声明时它的类型就是明确的 ...
- linux 下安装minconda3
一.关于bashrc目录,此文件是隐藏的,如果要打开此文件需要用: vim /root/.bashrc 二.linux下关于防火墙的命令 1.查看防火墙状态 firewall-cmd --state ...
- PowerShell 管道符之Select的使用方法【一】
之前我文章中我们略微提到过管道符的操作,但并不多,这篇主要讲解一下详细的使用方法 假设我们要对数组中的数字1-10中我想要从右往左换句话说就是从字符串最后一个字开始倒过来往前数截取6个子字符串时可以这 ...
- python驱动SAP完成数据导出(二)
在上一篇 python驱动SAP完成数据导出(一)中,我们提到了数据导出前,SAP布局的重要性,如何识别当前布局模式,以及如何切换到想要的布局.本篇小爬将着重讲讲数据导出的注意事项. 我们可以通过如下 ...