js继承(自备水,这非常干货)
讲js继承之前,想一想什么是继承? 生活中有很多例子,比方说继承财产,继承女朋友的前男友的前女友 ヽ(ー_ー)ノ ,这些和js继承差不多,但是有一个不一样的地方,就是继承过后,原先的人就没有了,js继承过后原先还有原先的属性。
最简单的继承 : 原型链继承(我最简单,也重要,也常见,不要因为简单看不起我,我很傲娇的 o(´^`)o)
原型链继承抓住了一个重要核心: 我指向的构造函数的实例就能访问原型的方法(没错,不需要理由谁叫我是你爸爸,我的方法给你用 ( ̄ェ ̄;)
(爸爸更新的技术儿子享受就行了,爸爸添加的方法给儿子用)
function Wife( ){
this.say : function(){
console.log( ' 今天你也很美,比月亮还美 ' )
}
} // 生一个儿子呗
var son = new Wife() // 找到老公并且给孩子他爹发明一个方法fn,有了这个方法可以说Hello了
Wife.prototype.fn = function() {
cosole.log('Hello')
} son.fn() // 'Hello'
(幸福生活没过多久,老公出轨,老婆和老公离婚,老婆不想找另一个男的,厉害了自己造一个,有鼻子有眼的,让他的心一直指向老婆constructor)
function Wife( ){
this.say : function(){
console.log( ' 今天你也很美,比月亮还美 ' )
}
} // 生一个儿子呗
var son = new Wife() // 新造一个老公
Wife.prototype = {
fn : function(){
console.log('老婆你最美')
},
say : '老婆最棒',
// 把心永远向着老婆
constructor : Wife
} son.fn() // '老婆你最美'
吸功大法:混入式继承 + 原型链继承 (在原型上定义一个混入式继承的方法)
function Wife(){
name : ' 仙女 ',
age : 20
} Wife.prototype.extend(obj){
for( var key in obj ){
if( obj.hasOwnProperty(key) ){
this[ key ] = obj [ key ]
}
}
} var wugong1 = {
'qiankun': '乾坤大挪移'
} var wugong2 = {
'xuanming': '玄冥神掌'
} var son = new Wife();
son.extend(wugong1)
son.extend(wugong2)
console.log(son) // 添加了wugong1,wugong2,this指向发生了改变,指向了son这个实例对象,所以是son添加了,而不是原型添加了wugong1,wugong2
(为什么不说混入继承,混入继承就是遍历一个对象,把对象的属性一个一个赋给另一个对象,有需求的话注意深浅拷贝)
构造函数借用 (缺点 : 方法必须也在构造函数里才能借用而借用过来的方法也在构造函数里,方法最好在原型上)
function Animal(name){
this.name = name;
this.try = function (){
console.log('叫声')
}
}
function Cat(){
Animal.call(this,name);
// 自己的属性
this.age = 3;
}
var cat = new Cat();
console.log(cat) // 有自己的age属性 有继承构造函数的name ,try方法
既然上述方法有方法继承的缺陷,那么不妨试试组合继承(结合原型继承【处理方法继承】 + 构造函数借用【处理属性继承】,缺陷是执行两次超类构造函数)
// 组合继承 简单的说通过借用在构造函数里继承属性、用被继承的实例指向继承的原型来继承方法
// 组合继承不能继承被继承原型里的方法,也就是方法要写在构造函数里
function Animal(name) {
this.name = name;
this.color = '我是毛色';
}
function Cat(name) {
// new的时候执行一次超类构造函数
Animal.call(this, name); //只继承属性
this.cry = '喵';
}
// 又执行一次超类(被继承类)构造函数
Cat.prototype = new Animal(); // 把被继承的构造函数实例对象充当继承构造函数的原型,根据属性查找原则,不用担心获取的和原型的冲突
Cat.prototype.constructor = Cat; // 因为原型覆盖了,所以要加上constructor
Cat.prototype.action = function() { // 可以在原型上新建方法
console.log('猫步');
};
var cat = new Cat('波斯');
console.log(cat);// Cat {name: "波斯", color: "我是毛色", cry: "喵"}
console.log(cat.__proto__);// Animal {name: undefined, color: "我是毛色", constructor: Cat, action: ƒ}
道格拉斯(可不是尼古拉斯【红宝书作者】)的原型式继承【从原型直接到实例唯一的不足就是属性不能从原型上继承,因为不同实例不好改属性值,只适合继承方法】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title></title>
<style></style>
</head>
<body>
<script>
var obj = {
name: 'zs',
friends: ['云云', '雪雪', '雨雨']
};
function object(o) {
function F() {}
F.prototype = o;
// 直接就不管构造函数与原型的联系,直接由原型继承
return new F();
}
var example1 = object(obj);
console.log(example1.friends.push('薇薇')); // 此举会改变obj这个对象,因为F.prototype = o是浅拷贝,导致以后实例受影响,这不算缺点
var example2 = object(obj);
console.log(example2.friends); // ['云云','雪雪','雨雨','薇薇']
</script>
</body>
</html>
最骚的继承 : 经典继承 var newObj = Object.create( obj ) newObj是obj.contructor的实例,不是构造函数,也就是直接__proto__逆操作,骚的一P(其实就是原型继承的强化版)
Es5规范了上述的原型继承,给object取名create,并挂到Object上,唯一的不同之处在于还有第二个可选参数是个对象{ 属性名 : { value : 属性值 } },当属性名不存在添加,已经存在原型上则为覆盖。【话说浅拷贝的问题依然存在】
寄生继承(原型继承基础上用另一个函数把原型继承的实例增强后返回出去,通过增加的方法还不是在原型上,所以复用性不高)
var obj = {
name: 'zs',
friends: ['云云', '雪雪', '雨雨']
};
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
function Parasitic(o) {
var newExample = object(o);
// 增强这个实例
newExample.sayHi = function() {
console.log('sayHi');
};
return newExample;
}
console.log(new Parasitic(obj));
最牛的继承 : 寄生组合继承
function object(o){
function Fn(){}
Fn.prototype = o;
return new Fn()
}
function SuperType(name){
this.name = name;
this.colors = ['red','green','blue']
}
SuperType.prototype.sayHi()= function() {
console.log('我是超类');
}
function SubType(name,age){
SuperType.call(this,name)
this.age = age;
}
function ParaComponent(SubType,SuperType){
var p = object(SuperType.prototype);
p.consructor = SubType;
SubType.prototype = p;
}
ParaComponent(SubType,SuperType);
SubType.prototype.sayAge = function(){
console.log('sayAge');
}
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继承实现
JS实现继承可以分为:对象冒充和原型链继承 其中对象冒充又包括:临时变量,call 和 apply 临时变量方法: function Person(name,sex){ this.name = nam ...
- js继承之借用构造函数继承
我的上一篇文章介绍了,原型链继承模式.但是单纯的原型链模式并不能很好地实现继承. 一.原型链的缺点 1.1 单纯的原型链继承最大的一个缺点,来自于原型中包含引用类型的值. 本来,我们没有通过原型链实现 ...
- js继承之原型链继承
面向对象编程都会涉及到继承这个概念,JS中实现继承的方式主要是通过原型链的方法. 一.构造函数.原型与实例之间的关系 每创建一个函数,该函数就会自动带有一个 prototype 属性.该属性是个指针, ...
- js继承的常用方法
写在前面的话:这篇博客不适合对面向对象一无所知的人,如果你连_proto_.prototype...都不是很了解的话,建议还是先去了解一下JavaScript面向对象的基础知识,毕竟胖子不是一口吃成的 ...
随机推荐
- [转]使用GetIfTable获取MIB_IFTABLE和MIB_IFROW获取网络接口信息
#include <iphlpapi.h> #pragma comment ( lib, "iphlpapi.lib") 使用GetIfTable()获取各个端口信息的 ...
- [Java]通过java获取计算机名
通过java获取计算机名 String hostname = "Unknown"; try { InetAddress addr; addr = InetAddress.getLo ...
- Windows环境和Linux环境下Redis主从复制配置
Windows环境下和Linux环境下配置Redis主从复制基本上一样,都是更改配置文件.Windows环境下修改的配置文件是:redis.windows.conf.redis.windows-ser ...
- DataStage 六、安装和部署集群环境
DataStage序列文章 DataStage 一.安装 DataStage 二.InfoSphere Information Server进程的启动和停止 DataStage 三.配置ODBC Da ...
- jquery从零开始学----选择器
(2011-01-10 21:21:28) 转载▼ 后代选择器: $("mix mix"),当然可以是多个嵌套,但后代选择器可以是深层子代,所以$("mix mix m ...
- jfinal框架教程
jfinal框架教程 下面通过一个小例子了解jfinal的结构和特点 1.建数据库(我用的是oracle数据库,其他的相对也差不多) -- Create table create table CLAS ...
- Java中的一些代理技术
使用cglib,asm 对接口进行拦截,这里需要调用Invoke方法 final IUserService userService=new UserService(); Enhancer enhanc ...
- Gym 101201H Paint (离散化+DP)
题意:给定 n 个区间,让你选出一些,使得每个选出区间不交叉,并且覆盖区间最大. 析:最容易想到的先是离散化,然后最先想到的就是 O(n^2)的复杂度,dp[i] = max(dp[j] + a[i] ...
- LARGE SCALE GAN TRAINING FOR HIGH FIDELITY NATURAL IMAGE SYNTHESIS
最强GAN图像生成器,真假难辨 论文地址: https://openreview.net/pdf?id=B1xsqj09Fm 更多样本地址: https://drive.google.com/driv ...
- (译)C#参数传递
前言 菜鸟去重复之Sql的问题还没有得到满意的答案.如果哪位大哥有相关的资料解释,能够分享给我,那就太谢谢了. 接触C#一年了,感觉很多东西还是很模糊,像C#中的委托和事件 有些东西看多了不用也还是不 ...