原型与原型链的学习理解
目录
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属性,也会给其添加该属性。
原型与原型链的学习理解相关推荐
- 在图书馆学习红宝书的一天(二)· 慢慢看原型、原型链就看懂了~
前言 大家好,这里是@IT·平头哥联盟,我是团宠闪光少女--粉刷酱. 要怎么描述编程是个多幸福的工作呢? 我们很多人都想着如果能一辈子编程,那真是太好了. 而现实生活中,对未来的担忧和焦虑常常困扰着我 ...
- 深入理解JavaScript系列(5):强大的原型和原型链
前言 JavaScript 不包含传统的类继承模型,而是使用 prototypal 原型模型. 虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大.实 ...
- 深入学习js之——原型和原型链
开篇: 在Brendan Eich大神为JavaScript设计面向对象系统的时候,借鉴了Self 和Smalltalk这两门 基于原型的语言,之所以选择基于原型的面向对象系统,并不是因为时间匆忙,它 ...
- js原型和原型链_理解JS中的原型和原型链
导读:JavaScript中(JS)的原型和原型链是web前端开发面试中经常被问到的问题:同时,如果我们能很好的理解JS中的原型和原型链,对于控制台输出的很多信息我们也能更好的理解,而原型链也是实现继 ...
- 原型和原型链的理解(Function,Object特例深入理解)
原型我们可以分为显式原型和隐式原型. 显式原型: 每个函数都有一个prototype属性,即显式原型(属性),它默认指向一个object空对象(称为原型对象): 而原型对象中有一个属性construc ...
- JavaScript的原型与原型链理解
简单描述了原型与原型链的理解,欢迎学习讨论. 构造函数 function A(){} 原型 构造函数都有prototype原型属性 A.prototype.name = 'wjx' 原型的 const ...
- JS原型、原型链深入理解
原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有"prototype"属性,函数对象有"prototype"属性,原型对象有&q ...
- 小汤学编程之JavaScript学习day04——自定义对象、原型与原型链、BOM
一.自定义对象 1.对象的定义 2.对象的使用 二.原型与原型链 1.JS的继承结构图 2.关键点 三.BOM 1.window对象 2.document对象 3.lo ...
- [我的理解]Javascript的原型与原型链
一.原型与原型链的定义 原型:为其他对象提供共享属性的对象 注:当构造器创建一个对象,为了解决对象的属性引用,该对象会隐式引用构造器的"prototype"属性.程序通过const ...
最新文章
- java逻辑符号怎么打_Java的逻辑运算符?
- android adb打开gps,adb 命令行模拟GPS位置信息
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
- px ,em ,rem
- 如何将SAP数据传输到其他系统(Transferring Data from SAP to Other Systems)
- windows如何生成ssh密钥
- 余承东:华为Mate 30 RS保时捷设计 9月19日发布
- eclipse中将java项目变成web项目
- docker 1.8+之后ubuntu安装指定版本docker-engine
- 自食其力!ASP.NET 4打造HTML5视频控件
- MVP Open Day 2011
- 47结构图纸_2019年1月压力容器设计审批人员培训考核班图纸答辩试题
- c语言程序游戏例子,C语言游戏编写例子.doc
- 精密光纤激光打标机目前技术如何
- 华为网络设备-DHCP基础配置实验
- 到底什么是非线性优化?
- java mail类_Java Mail工具类
- laravel常见错误(一):The page has expired due to inactivity. Please refresh and try again.
- VR全景电子商务增加客户体验
- AMS1117-ADJ的使用
热门文章
- python+opencv直方图均衡化
- 怎样用手机把视频变成GIF表情包?原来那么简单,网友:看完涨知识了
- 亲测好用的6个临时邮箱推荐
- 2020 JAVA eclipse 中文汉化包 安装教程--傻瓜式操作
- 常用的 Druid 参数
- 打造一支有服务能力的销售队伍
- Ubuntu快捷键——终端
- 哦耶OYE-0001 OpenWrt路由器折腾记(by quqi99)
- 田野调查手记·浮山篇(一)
- Required field ‘serverProtocolVersion‘ is unset! User: root is not allowed to impersonate root