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 因此这个方法是最完美的

以上就是本次内容的分享,感谢各位老哥的阅读

最新文章

  1. 【转】深入浅出Android Support Annotation
  2. Shell概述
  3. Git基本交互流程图
  4. apache common包下的StringUtils的join方法
  5. 如何设置textarea光标默认为第一行第一个字符
  6. wndows常用命令
  7. Asycn/Await 异步编程初窥(二)
  8. SignalR的坑爹细节
  9. 了解 : angular controller link ng-init 顺序
  10. springboot之Jwt验证
  11. Webpack 2 视频教程 009 - 配置 ESLint 实现代码规范自动测试 (上)
  12. 阿里云对象存储 OSS 应用服务器搭建代码
  13. spring整合junit
  14. python中3个连续的单引号是什么意思?''' ... ''' 这样的引号是什么意思?
  15. python2.7安装和uwsgi
  16. [二维码开发]二维码开发入门级demo
  17. 线程属性 pthread_attr_t
  18. 我的Java之旅 第三课 从Applet到JSP
  19. ABBYY FineReader Pro for Mac有哪些特性(下)
  20. PasteDeploy部署Pecan API 服务

热门文章

  1. 关于WIN7下IE8IE7浏览器无法安装微信支付商户证书的解决方案
  2. HTTP Error 500.35 - ANCM Multiple In-Process Applications in same Process
  3. Ubuntu 安装最新版nodejs
  4. Java生鲜电商平台-深入订单拆单架构与实战
  5. 软件设计之基于Java的连连看小游戏(二)——游戏基础界面的制作及事件的添加
  6. 使用原生Ajax进行用户名重复的检验
  7. 工具类ToastUtil 避免在子线程中使用抛异常 "Can't create handler inside thread that has not called Looper.prepare()"
  8. Mybatis书写
  9. 判断map是否包含另一个map
  10. RabbitMQ获取队列的消息数目