目录

1.对象和函数的原型

1.1认识对象的原型

1.2函数的原型

1.3 将方法放到原型上

1.4总结:

1.5思考:

2.显式原型的属性

2.1默认属性

2.2重写原型对象

3.面向对象的特性——继承

那么继承能做什么呢?

原型链实现继承

原型式继承的渊源


ES5:

1.对象和函数的原型

1.1认识对象的原型

每一个对象都有自己的原型。

如何获取我们的原型?

疑问:这个原型有什么用???

当我们通过[[get]]方式获取一个属性对应的value时,

1)它会优先在自己的对象中查找,如果找到直接返回

2)如果没有找到,那么会在原型对象中查找

可以看到,如果对象中不存在但是原型链中存在的话,返回值不会是undefined。如果都没有则返回undefined。

那么我们尝试通过对原型添加属性,再通过对象获取,可以看到原型里面添加了这个属性,也能获取到该属性。

1.2函数的原型

1.将函数看作一个普通对象(隐式原型)

2.将函数看成一个函数,其具备prototype(注意:对象是没有prototype!!)(显式原型)

prototype:只有函数才具备显式原型

回顾new操作new Person()

1.创建一个空对象

var obj = {}

2.将this指向该对象

this = obj

2.5.将函数的显式原型赋值给这个对象作为隐式原型(可作为第二步/第三步)

obj.__proto__ = Person.prototype

3.执行函数中的代码

4.将这个对象返回

1.3 将方法放到原型上

当我们创建一个构造函数的时候,如果创建对象,调用构造函数里面的方法时,每创建一个对象调用相应的方法,就会创建一个新的方法,其实这是没有必要当,当我们创建非常多的对象时,这样就会造成空间资源的浪费,是非常没有必要的。

由上面两张图可以看出来:每个对象调用构造函数里面的方法时,都会创建新的方法。所以我们可以用prototype来把方法创建在原型上。

如下:

当把方法放在原型上面,调用的方法都是同一个方法。

但是,为什么能够调用呢?

stu1的隐式原型就是Student的显式原型;

怎么查找自己的原型?(stu1举例)

*现在自己身上查找,没有找到;

*去原型上查找。

stu2的隐式原型也是Student的显示原型。

所以:当我们多个对象拥有共同的值时,可以将其放在构造函数的显式原型上,由构造函数创建出来的所有对象,都会共享这些属性。

1.4总结:

1.什么是函数的显式原型?

区分和对象原型的区别。

2.函数原型的作用?

再通过new操作创建对象时,将这个显式原型赋值给创建出来的对象的隐式原型。

3.案例Person,将所有的函数定义放在显式原型上,所有的对象都可以共享这些方法。

1.5思考:

属性为什么不放在原型上?

每个对象都有自己独有的属性。

2.显式原型的属性

2.1默认属性

事实上,原型对象都有一个属性:constructor

默认情况下原型上都会添加一个属性叫做constructor,这个constructor指向当前的函数对象。

打印后发现原型的数据类型是:object

刷新后发现,其中有constructor(构造器)属性。

首先提取出Person的prototype属性,对属性内的constructor进行打印,发现constructor指向了Person函数对象。所以这之间存在循环引用的。

实例对象举例:

可以看到,constructor属性都是同一个。

内存指向:

验证如下:

2.2重写原型对象

从上图可以看到有个缺点:

在未重写原型时,我们发现原型里面并不能枚举出来constructor属性,但是在重写原型后,是可以枚举出来constructor属性的,这就与浏览器的默认方法不一致,那么如何解决这个问题?

从上图可以看到:仍然添加了constructor属性,但是枚举时不显示。

3.面向对象的特性——继承

面向对象:一种编程方式。

面向对象有三大特性:封装、继承、多态

  • 封装:我们将属性和方法封装到一个类中,可以称之为封装的过程;

例如:

var name = 'lu';
var age = 26;
function running () {}function info = {name: 'lu',age: 26,running: function() {}
}
// 如果有很多类似的东西,我们也可以把其放到类里,这也叫封装
  • 继承是面向对象中非常重要的,不仅仅可以减少重复代码的数量,也是多态前提(纯面向对象中);
  • 多态:不同的对象在执行时表现出不同的形态;

那么继承能做什么呢?

  • 继承可以帮助我们将重复的代码和逻辑抽取到父类中,子类只需要直接继承过来使用即可;
  • 在很多编程语言中,继承也是多态的前提

向上面这样,我们的学生和老师类都有很多共同的属性和方法,这个时候,只需要把共同的属性和方法放到父类里面,子类只需要继承。

所以这个时候讲解一下原型链的概念。

查找顺序:

1.obj上查找

2.obj.__proto__上查找

3.obj.__proto__.__proto__ -> null上查找(undefined)

对现有代码进行改造:

假设前两个原型添加message属性:

所以得到了如下结论:

 这样一个链式查找过程就叫做:原型链。

所以继承类似,当我们在子类中查找不到时,就可以去父类中查找,所以就可以把所有的子类中相同的属性都放到父类中,以此类推。

原型链实现继承

什么地方是原型的尽头呢?

当我们一直打印原型__proto__属性会发现在最后返回null。

事实上,这个原型就是我们最顶层的原型了。

从Object上直接创建出来的对象原型都是null。

那么我们思考,该原型有什么特殊的吗?

1.该对象有原型属性,但是其原型属性已经指向null,已经是顶层原型了;

2.该对象上有很多默认的属性和方法;

我们先不使用继承创建一个Person类和一个Student类。

(下图的Student的s应该大写,后面改了,下面这张图懒得改了)

一个错误示例:

首先考虑方法的继承:

原型链的弊端:

1.我们通过直接打印对象是看不到这个属性的;

2.这个属性会被多个对象共享,如果这个对象是一个引用类型,那么就会造成问题;

3.不能给Person传递参数(让每个stu有自己的属性),因为这个对象是一次性创建的,没办法定制化;

考虑属性的继承:

组合继承:

方法继承+属性继承。

组合继承存在什么问题?

1.无论在什么情况下,都会调用两次父类构造函数;

  • 一次在创建子类原型的时候;
  • 一次在子类构造函数内部(就是每次创建子类实例的时候);

2.所有子类实例事实上都会拥有两份父类属性

  • 一份在当前的实例自己里面(也就是Person本身),另一份在子类对应的原型对象中(也就是person.__proto__里面);
  • 默认访问实例本身;

原型式继承的渊源

那么我们如何解决这个问题?

满足条件:

1.必须创建出来一个对象

2.这个对象的隐式原型必须指向父类的显式原型

3.将这个对象赋值给子类的显式原型

在真实的开发中,一般都会对其进行封装成函数,并且因为创建对象里面不存在constructor属性,也会给其添加该属性。

原型与原型链的学习理解相关推荐

  1. 在图书馆学习红宝书的一天(二)· 慢慢看原型、原型链就看懂了~

    前言 大家好,这里是@IT·平头哥联盟,我是团宠闪光少女--粉刷酱. 要怎么描述编程是个多幸福的工作呢? 我们很多人都想着如果能一辈子编程,那真是太好了. 而现实生活中,对未来的担忧和焦虑常常困扰着我 ...

  2. 深入理解JavaScript系列(5):强大的原型和原型链

    前言 JavaScript 不包含传统的类继承模型,而是使用 prototypal 原型模型. 虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大.实 ...

  3. 深入学习js之——原型和原型链

    开篇: 在Brendan Eich大神为JavaScript设计面向对象系统的时候,借鉴了Self 和Smalltalk这两门 基于原型的语言,之所以选择基于原型的面向对象系统,并不是因为时间匆忙,它 ...

  4. js原型和原型链_理解JS中的原型和原型链

    导读:JavaScript中(JS)的原型和原型链是web前端开发面试中经常被问到的问题:同时,如果我们能很好的理解JS中的原型和原型链,对于控制台输出的很多信息我们也能更好的理解,而原型链也是实现继 ...

  5. 原型和原型链的理解(Function,Object特例深入理解)

    原型我们可以分为显式原型和隐式原型. 显式原型: 每个函数都有一个prototype属性,即显式原型(属性),它默认指向一个object空对象(称为原型对象): 而原型对象中有一个属性construc ...

  6. JavaScript的原型与原型链理解

    简单描述了原型与原型链的理解,欢迎学习讨论. 构造函数 function A(){} 原型 构造函数都有prototype原型属性 A.prototype.name = 'wjx' 原型的 const ...

  7. JS原型、原型链深入理解

    原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有"prototype"属性,函数对象有"prototype"属性,原型对象有&q ...

  8. 小汤学编程之JavaScript学习day04——自定义对象、原型与原型链、BOM

    一.自定义对象 1.对象的定义     2.对象的使用 二.原型与原型链 1.JS的继承结构图     2.关键点 三.BOM 1.window对象     2.document对象     3.lo ...

  9. [我的理解]Javascript的原型与原型链

    一.原型与原型链的定义 原型:为其他对象提供共享属性的对象 注:当构造器创建一个对象,为了解决对象的属性引用,该对象会隐式引用构造器的"prototype"属性.程序通过const ...

最新文章

  1. java逻辑符号怎么打_Java的逻辑运算符?
  2. android adb打开gps,adb 命令行模拟GPS位置信息
  3. ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
  4. px ,em ,rem
  5. 如何将SAP数据传输到其他系统(Transferring Data from SAP to Other Systems)
  6. windows如何生成ssh密钥
  7. 余承东:华为Mate 30 RS保时捷设计 9月19日发布
  8. eclipse中将java项目变成web项目
  9. docker 1.8+之后ubuntu安装指定版本docker-engine
  10. 自食其力!ASP.NET 4打造HTML5视频控件
  11. MVP Open Day 2011
  12. 47结构图纸_2019年1月压力容器设计审批人员培训考核班图纸答辩试题
  13. c语言程序游戏例子,C语言游戏编写例子.doc
  14. 精密光纤激光打标机目前技术如何
  15. 华为网络设备-DHCP基础配置实验
  16. 到底什么是非线性优化?
  17. java mail类_Java Mail工具类
  18. laravel常见错误(一):The page has expired due to inactivity. Please refresh and try again.
  19. VR全景电子商务增加客户体验
  20. AMS1117-ADJ的使用

热门文章

  1. python+opencv直方图均衡化
  2. 怎样用手机把视频变成GIF表情包?原来那么简单,网友:看完涨知识了
  3. 亲测好用的6个临时邮箱推荐
  4. 2020 JAVA eclipse 中文汉化包 安装教程--傻瓜式操作
  5. 常用的 Druid 参数
  6. 打造一支有服务能力的销售队伍
  7. Ubuntu快捷键——终端
  8. 哦耶OYE-0001 OpenWrt路由器折腾记(by quqi99)
  9. 田野调查手记·浮山篇(一)
  10. Required field ‘serverProtocolVersion‘ is unset! User: root is not allowed to impersonate root