js继承实现
在js里面,继承总是晦涩难懂的。那让我们一步一步来分析js继承。
首先,继承的目的。我们可以通过new一个构造器的实例对象,就可以实现调用父类的所有的方法。根本不需要propotype之类的。
来段代码理解下:
var Person = function(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
};
};
var person1 = new Person("bella", 23);
console.log(person1);

这里没有用到prototype,person1对象可以直接调用Person构造器中的属性和方法。
那我们为什么要用到prototype呢?说明通过new一个实例对象的方法是存在缺陷的 。那我们就来分析下,这个缺陷到底是什么?
var Person = function(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
};
};
var person1 = new Person("bella", 23);
var person2 = new Person("alex", 2);
console.log(person1);
console.log(person2);
console.log(person1.sayName === person2.sayName);

我们可以看到person1.sayName 不等于person2.name。意味着person1复制了一份sayName,person2也复制了一份sayName. 这样就比较消耗内存了。
于是我们想要person1和person2两个调用的时同一个sayName,像引用对象一样,调用同一个引用。
于是就引出了prototype,__proto__,原型链。如果这些知识不懂,先自行搞懂这些。
我们打印下person1对象,都有哪些东东?

可以看到有age,name,sayName除外,还有__proto__隐式原型。
__proto__里面有constructor 和__proto__.那我们就着重看下这个construtor和__proto__
每个对象都有个__proto__。__proto__.constructor又指向自己,相当于__proto__.constructor = Person;
__proto__.__proto__ = Person.prototype
那如果实现继承需要实现什么?
一个Parent构造器和一个Child构造器。然后Child继承Person,需要实现什么?
第一步,肯定需要实现Person构造器里面的。
.call(this);
第二步,就是通过原型链的原理实现,继承父类原型上的属性和方法。
Child子类的prototype 里面有constructor和__proto__属性。
那么继承原理就是:
Child.prototype.constructor = Child;
Child.prototype.__proto__ = Parent.prototype;
这样Child就可以通过原型链找到Parent原型上的方法了。
所以原理就是第一步和第二步里面标红的3行代码了。
实现如下:
var Parent = function(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
};
};
Parent.prototype.sayAge = function() {
console.log(this.age);
};
var Child = function(name, age) {
Parent.call(this, name, age);
};
Child.prototype.__proto__ = Parent.prototype;
Child.prototype.constructor = Child;
var child = new Child("bella", 23);
console.log(child);
输出结果:

但是js里面一般不直接操作__proto__属性,所以有了更优化的方案。
var Parent = function(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
};
};
Parent.prototype.sayAge = function() {
console.log(this.age);
};
var Child = function(name, age) {
Parent.call(this, name, age);
};
var Temp = function() {};
Temp.prototype = Parent.prototype;
var temp = new Temp();
temp.constructor = Child;
Child.prototype = temp;
// Child.prototype.__proto__ = Parent.prototype;
// Child.prototype.constructor = Child;
var child = new Parent("bella", 23);
console.log(child);
标红部分就是优化之后的代码。很多看着会一脸懵。为什么这个算是优化的?我怎么看不懂。
需要看懂这个的,首先需要了解new Temp()这个过程做了什么?
new做了什么,自行去了解。我把new的过程写下来:
var temp =new Temp();
//上面一步相当于下面四步
var obj={};
Temp.call(this);
obj.__proto__ = Temp.prototype;
var temp = obj;
这样一来是不是有点明白了。
var Temp = function() {};
Temp.prototype = Parent.prototype;
var temp = new Temp();
这三步就先相当于是
Child.prototype.__proto__ = Parent.prototype;
temp.constructor = Child;
这一步相当是
Child.prototype.constructor = Child;
现在的temp就包含了需要继承的Parent的__proto__和指向Child的constructor.
然后再把temp赋值给Child.prototype就实现了继承。 所以理解完这个之后,继承看起来也没有那个晦涩难懂了。
js继承实现的更多相关文章
- js继承
js继承有5种实现方式: 继承第一种方式:对象冒充 function Parent(username){ this.username = username; this.hello = function ...
- js继承之call,apply和prototype随谈
在js中,call,apply和prototype都可以实现对象的继承,下面我们看一个例子: function FatherObj1() { this.sayhello = "I am jo ...
- js继承精益求精之寄生式组合继承
一.混合/组合继承的不足 上一篇JS继承终于混合继承,认真思考一下,发现其还是有不足之处的: 空间上的冗余:在使用原型链的方法继承父类的原型属性(Animal.prototype)的同时,也在子类的原 ...
- 老生常谈--Js继承小结
一直以来,对Js的继承有所认识,但是认识不全面,没什么深刻印象.于是,经常性的浪费很多时间重新看博文学习继承,今天工作不是特别忙,有幸看到了http://www.slideshare.net/stoy ...
- Js继承小结
Js继承小结 一直以来,对Js的继承有所认识,但是认识不全面,没什么深刻印象.于是,经常性的浪费很多时间重新看博文学习继承,今天工作不是特别忙,有幸看到了http://www.slideshare.n ...
- js继承之借用构造函数继承
我的上一篇文章介绍了,原型链继承模式.但是单纯的原型链模式并不能很好地实现继承. 一.原型链的缺点 1.1 单纯的原型链继承最大的一个缺点,来自于原型中包含引用类型的值. 本来,我们没有通过原型链实现 ...
- js继承之原型链继承
面向对象编程都会涉及到继承这个概念,JS中实现继承的方式主要是通过原型链的方法. 一.构造函数.原型与实例之间的关系 每创建一个函数,该函数就会自动带有一个 prototype 属性.该属性是个指针, ...
- js继承的常用方法
写在前面的话:这篇博客不适合对面向对象一无所知的人,如果你连_proto_.prototype...都不是很了解的话,建议还是先去了解一下JavaScript面向对象的基础知识,毕竟胖子不是一口吃成的 ...
- JS--我发现,原来你是这样的JS:面向对象编程OOP[3]--(JS继承)
一.面向对象编程(继承) 这篇博客是面向对象编程的第三篇,JS继承.继承顾名思义,就是获取父辈的各种"财产"(属性和方法). 怎么实现继承? 我们的JavaScript比较特别了, ...
随机推荐
- 一步步优化JVM三:GC优化基础
本节主要描述关于垃圾回收器性能的三个指标,三个关于垃圾回收器优化的基本原则,以及优化HotSpot VM的垃圾回收器的信息收集,在这些指标中权衡以及信息的收集是非常重要的. 性能指标 吞吐量:衡 ...
- Python 学习笔记13:Python + wsgi + django 配置。坑爹的python3和wsgi不兼容的解决
今人不见古时月,今月曾经照古人.生命是如此的美丽与短暂! 学习Python已经两个月了,Python的语法通过做简单的语法题和看Python语法介绍,有了初步的了解.但上班还是要做别的事情,所以感觉学 ...
- 在iOS9中 xcode7 网络请求 如图片请求不显示等
Application Transport Security has blocked a cleartext HTTP (http://) resource load since it is inse ...
- Java作用域
1. java访问控制修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java支持4种不同的访问权限. 默认的,也称为 default,在同一包内可见,不使用任何修饰符. ...
- Xcode 8 控制台输出大量不用的log的问题解决&&NSLog失效的解决
Product-->Scheme-->editeScheme中:Auguments中Environment Variable中 Scheme中添加环境变量 "OS_ACTIVIT ...
- tomcat + jenkins启动tomcat后打开jenkins页面提示404错误的解决方案
首先下载tomcat和jenkins,将下载的jenkins2.12 war放到tomcat的webapps文件夹下后执行/bin文件夹下的start启动后,打开http://localhost:80 ...
- JAVA 程序发布引发性能抖动
发布或重启线上服务时抖动问题解决方案 一.问题描述 在发布或重启某线上某服务时(jetty8作为服务器),常常发现有些机器的load会飙到非常高(高达70),并持续较长一段时间(5分钟)后 ...
- 最近遇到的两个IE下的问题(IE兼容问题)
最近遇到了两个IE下的兼容问题(产品目前还需要兼容IE8,所以没办法,运行效果虽然不好,但是也仍然兼容着吧) 问题描述: 1, 在更改IE窗口的时候,反应非常慢,甚至卡死 2, 在chrome运行正常 ...
- react总结
在我的工作用到的最多就是backbone,其次还会有ember/Ext,backbone目前能实现我们team所需要实现的功能,因为我们的component不需要频繁的操作Dom,当后台API返回数据 ...
- Nohttp框架在Android Studio中的使用
1.添加noHttp的使用权限 <!-- 读写 sd 卡 --> <uses-permission android:name="android.permission.REA ...