原型链

定义:每个实例对象(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之原型链与原型链继承的更多相关文章

  1. 《JAVASCRIPT高级程序设计》根植于原型链的继承

    继承是面向对象的语言中,一个最为津津乐道并乐此不疲的话题之一.JAVASCRIPT中的继承,主要是依靠原型链来实现的.上一篇文章介绍过,JAVASCRIPT中,每一个对象都有一个prototype属性 ...

  2. Javascript原型链和原型继承

    哇好久都没有写随笔啦,整个人都慵懒啦. 为了不让大家忘记我,把以前写过的一些慢慢发出来. 在JS 中, 有两条链子,作用域链 和 原型链. 作用域链相对容易理解,两点 - 函数限定变量作用域,就是说, ...

  3. javascript中的对象,原型,原型链和面向对象

    一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...

  4. 【javascript基础】4、原型与原型链

    前言 荒废了好几天,在宿舍闷了几天了,一直想着回家放松,什么也没搞,论文就让老师催吧.不过,闲的没事干的感觉真是不好,还是看看书,写写博客吧,今天和大家说说函数的原型. 原型是什么 第一次看到这个的时 ...

  5. JavaScript探秘:强大的原型和原型链

    // foo 变量是上例中的 for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i); } } JavaScript 不包括传统 ...

  6. javascript中的构造函数和原型及原型链

    纯属个人理解,有错误的地方希望大牛指出,以免误人子弟 1.构造函数: 构造函数的作用 : 初始化由new创建出来的对象    new 的作用: 创建对象(空对象) new 后面跟的是函数调用,使用ne ...

  7. JS原型,原型链,类,继承,class,extends,由浅到深

    一.构造函数和原型 1.构造函数.静态成员和实例成员 在ES6之前,通常用一种称为构造函数的特殊函数来定义对象及其特征,然后用构造函数来创建对象.像其他面向对象的语言一样,将抽象后的属性和方法封装到对 ...

  8. [js高手之路]一步步图解javascript的原型(prototype)对象,原型链

    我们接着上文继续,我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉. function CreateObj(uName) { this ...

  9. js 原型,原型链,原型链继承浅析

    对于网上的关于原型,原型链和原型链继承的晦涩语言说明就不累赘了,复制粘贴过来再解释一遍怕自己也整蒙了,本人最怕空气突然安静,四目对视,大眼对小眼,一脸懵逼. 我们先看下面

  10. 【javascript】对原型对象、原型链的理解

    原型对象,原型链这些知识属于基础类知识.但是平时开发过程中也很少用到. 看网上的意思,原型链用于es5开发场景下的继承.es6有了类语法糖之后,就自带继承了. 通过理解,个人画了一张原型链解构的关系图 ...

随机推荐

  1. 【LeetCode】731. My Calendar II 解题报告(Python)

    [LeetCode]731. My Calendar II 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题 ...

  2. 【LeetCode】491. Increasing Subsequences 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  3. 1161 - Extreme GCD

    1161 - Extreme GCD    PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 32 MB All ...

  4. Centos/Docker/Nginx/Node/Jenkins 操作

    Centos Centos 是一个基于 Linux 的开源免费操作系统 # 本地拷贝文件到远程服务器scp output.txt root@47.93.242.155:/data/ output.tx ...

  5. Linux环境下Django App部署到XAMPP上

    Django App部署到XAMPP上 准备工作 首先一定要保证自己的代码在本地可以运行! 同时在服务器上把需要的库,什么数据库之类的都装好! 源码安装mod_wsgi 从mod_wsgi的gitgu ...

  6. Mysql溯源-任意文件读取👻

    Mysql溯源-任意文件读取 前言 读了<MySQL蜜罐获取攻击者微信ID>的文章,文中说明了通过mysql蜜罐读取攻击者微信ID的过程,抱着学习的态度尝试了一下 原理 mysql中有一个 ...

  7. Browser Events 常用浏览器事件

    事件 说明 click 鼠标点击时触发此事件 dblclick 鼠标双击时触发此事件 mousedown 按下鼠标时触发此事件 mouseup 鼠标按下后松开鼠标时触发此事件 mouseover 当鼠 ...

  8. Java中对象的内存分配机制

    一.内存划分 Java把内存划分为两种,一种是栈内存,另一种是堆内存. 1.栈内存 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配.当在一段代码块定义一个变量时,Java就在栈 ...

  9. 查看电脑内存是ddr3还是ddr4

    内存不够用了 要加个内存 但是不想拆机 怎么知道自己电脑是第几代内存呢? 怎么知道频率呢? 1.运行cmd 2.输入wmic回车 3.输入memorychip回车 4.往右拉找到Speed Statu ...

  10. Storm对DRPC权限控制Version1.0.1

    对Storm的DRPC进行权限控制, 并且设计相应的测试验证. 1.集群安装 请参考Storm集群安装Version1.0.1 2.使用DRPC功能 请参考Storm集群使用DRPC功能Version ...