JavaScript的__proto__、prototype和继承
JavaScript也是可以“继承”的!
各位看官或是好奇,或是一知半解。什么是prototype,__proto__,constructor、哪种继承方式好。今天就在这交流交流。
什么是prototype,__proto__,constructor
https://blog.csdn.net/cc18868876837/article/details/81211729 (尊重原作者,这是篇超级好的文章,一定要点进去细细研读)
上面文章已经讲的很明白了,最后对文章总结再解释一下
第一点主要强调,我们拿到一个对象,主要看它什么,因为JavaScript中一切都是对象,所以在理解的时候很容易因为它有其他变量也混淆,所以我们研究一个对象,首先要确定我们的目标是什么,如果目标是对象,则抓住__proto__和constructor属性,如果目标是函数则抓住prototype属性,这样才能快速找到自己想要的东西解决问题。
第2,3,4点是关于哪种继承方式好的关键,一定要弄懂,下面再解释一下new关键词做了什么(没准你不懂上面文章写的,看懂我的例子)。
new关键词做了什么
//例如
var child = new Parent(); //上面这句代码就等于下面三句
var child = {};
child.__proto__ = Parent.prototype;
Parent.call(child);
咳咳,就跟教育孩子一样,孩子出生是张白纸(var child = {}),然后继承了父母的一些行为(就是方法),例如怎么说话啊,喜欢吃什么啊(child.__proto__ = Parent.prototype;),最后得到父母的一些人生经验,就是复制了属性变量(Parent.call(child))。
这里需要注意,孩子是不能生孩子的,即
var child2 = new child()
绝对报错的,对象是对象,并不是函数,也不会变成函数。
哪种继承方式好
继承能够代码复用,能让逻辑更清晰,所以是很有必要的,那怎么样继承效果最好呢
https://www.cnblogs.com/humin/p/4556820.html#(尊重原作者,这是篇超级好的文章,一定要点进去细细研读,这话好像有点熟悉)
推荐给大家一个方法,打开谷歌浏览器,按F12,在里面可以进行简单的练习
文章最好从第一个继承开始,就自己动手模拟一下,看看变量的__proto__和prototype到底指什么
而且从第一个继承方法演变到最完美的一个,这个思考过程是十分重要的。
我来再解释一下最完美的继承模式:寄生组合继承
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){
// 创建一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype = new Super();
})(); // Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true 感谢 @bluedrink 提醒,该实现没有修复constructor。 Cat.prototype.constructor = Cat; // 需要修复下构造函数
第7-10行的代码为什么这样做
通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点 这句话什么意思
回到刚才对new的解释,假设如组合5:组合继承一样
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal(); 第5行代码相当于:
Cat.prototype = {}
Cat.prototype.__proto__ = Animal.prototype
Animal.call(Cat.prototype) //这一步是多余的并不需要 所以 var Super = function(){}; 一个空方法来代替,因为只需要 Cat.prototype.__proto__ = Animal.prototype 就可以了
而现在Super.prototype = Animal.prototype 因此这个方法是最完美的
以上就是本次内容的分享,感谢各位老哥的阅读
最新文章
- 【转】深入浅出Android Support Annotation
- Shell概述
- Git基本交互流程图
- apache common包下的StringUtils的join方法
- 如何设置textarea光标默认为第一行第一个字符
- wndows常用命令
- Asycn/Await 异步编程初窥(二)
- SignalR的坑爹细节
- 了解 : angular controller link ng-init 顺序
- springboot之Jwt验证
- Webpack 2 视频教程 009 - 配置 ESLint 实现代码规范自动测试 (上)
- 阿里云对象存储 OSS 应用服务器搭建代码
- spring整合junit
- python中3个连续的单引号是什么意思?''' ... ''' 这样的引号是什么意思?
- python2.7安装和uwsgi
- [二维码开发]二维码开发入门级demo
- 线程属性 pthread_attr_t
- 我的Java之旅 第三课 从Applet到JSP
- ABBYY FineReader Pro for Mac有哪些特性(下)
- PasteDeploy部署Pecan API 服务
热门文章
- 关于WIN7下IE8IE7浏览器无法安装微信支付商户证书的解决方案
- HTTP Error 500.35 - ANCM Multiple In-Process Applications in same Process
- Ubuntu 安装最新版nodejs
- Java生鲜电商平台-深入订单拆单架构与实战
- 软件设计之基于Java的连连看小游戏(二)——游戏基础界面的制作及事件的添加
- 使用原生Ajax进行用户名重复的检验
- 工具类ToastUtil 避免在子线程中使用抛异常 ";Can't create handler inside thread that has not called Looper.prepare()";
- Mybatis书写
- 判断map是否包含另一个map
- RabbitMQ获取队列的消息数目