搞懂js继承方法
2017-04-23 13:34
141 查看
js实现继承,都是些老生常谈的问题了,网上文章很多,但不动手敲一敲,还是没有那种深入的理解,所以写篇日记记一下自己对继承的理解,如果顺便能帮到大家理解如何继承那是再好不过的了。最近也好久没写文章了,以后一定要经常写,来巩固自己的知识。
首先思考下,什么是继承,也就是我子元素能用父元素的方法,那该如何实现呢,我们都知道js中有原型这东西,当我们new一个对象的时候,new出来的对象就会有prototype上的属性和方法,我们看一下例子
我们可以看到stu1可以调用stu的方法,是不是有点像继承了呢?那我们继续,首先我们在创建一个构造函数
那我们如何让codeboy的实例能调用到上面的sayName方法呢,我们思考下,也就是说codeboy的实例可以使用codeboy.prototype里的属性和方法,那我们把stu的方法想办法放进codeboy.prototype里不就好了。那只需要codeboyprototype是stu的实例不就可以了么
这就是经典的原型链继承,我们把qfy的结构console出来看下
我们可以注意到一个属性叫
那这种方法是否有缺点呢,答案一定是有 对原型了解的同学一定知道,原型上的属性是共有的,那如果我对原型属性进行操作,我的其他实例都会受到影响。我们看下还是刚才的例子
通过上面的例子我们可以看出原型继承的缺点来,但又没有办法解决呢,当然有啦。我们继续思考,刚才我们是在codeboy的prototype上做了手脚,那我们能不能从codebody的构造函数上做手脚呢?
我们来想下
通过call实现了我们qfy使用了codeboy.prototype里的属性和方法。那我们是不是也可以通过在codeboy里调用call来继承呢。
可以看到我们的qfy中的this.name = ‘qfy’这就是借构造函数继承,但缺点也看到了,非常消耗内存,因为没有原型共享需要每次执行构造器而且没有原型链无法动态修改,但速度优秀因为不需要从原型链向上查找。没有了原型链就不存在共享的问题,所以上面的问题就可以解决。
介于上面的方法,我们可以将他们给组合起来,我们可以将需要复用的方法写在prototype而把不能共享的数据放在构造函数里通过this来赋值
这种方式就是组合继承,是最常用的继承方式,写到这就差不多写完了,还有一些其他不常见的继承方式,大家可以自行百度一下吧。
首先思考下,什么是继承,也就是我子元素能用父元素的方法,那该如何实现呢,我们都知道js中有原型这东西,当我们new一个对象的时候,new出来的对象就会有prototype上的属性和方法,我们看一下例子
function stu() { this.name = 'qfy'; } stu.prototype.age = 21; stu.prototype.sayAge = function() { return this.age } var stu1 = new stu() console.log(stu1.sayAge())//21
我们可以看到stu1可以调用stu的方法,是不是有点像继承了呢?那我们继续,首先我们在创建一个构造函数
function codeboy() { this.like = 'code'; }
那我们如何让codeboy的实例能调用到上面的sayName方法呢,我们思考下,也就是说codeboy的实例可以使用codeboy.prototype里的属性和方法,那我们把stu的方法想办法放进codeboy.prototype里不就好了。那只需要codeboyprototype是stu的实例不就可以了么
codeboy.prototype = new stu() var qfy = new codeboy() qfy.constructor = codeboy;//如果没有这句构造器为stu,而我们是codeboy的实例,所以需要修改指向 console.log(qfy.sayAge())//21
这就是经典的原型链继承,我们把qfy的结构console出来看下
我们可以注意到一个属性叫
__proto__这就是原型链,在这条链上的属性或方法我们都可以访问的到
那这种方法是否有缺点呢,答案一定是有 对原型了解的同学一定知道,原型上的属性是共有的,那如果我对原型属性进行操作,我的其他实例都会受到影响。我们看下还是刚才的例子
stu.prototype.likes = ['read','code'];//我们添加一个引用属性likes var qfy = new codeboy() var qfy1 = new codeboy() qfy.likes.push('eat') console.log(qfy1.likes)//[ 'read', 'code', 'eat' ]
通过上面的例子我们可以看出原型继承的缺点来,但又没有办法解决呢,当然有啦。我们继续思考,刚才我们是在codeboy的prototype上做了手脚,那我们能不能从codebody的构造函数上做手脚呢?
我们来想下
var qfy = new codeboy()的时候到底发生了什么事情
//1 //创建了一个空的{}并且继承codeboy.prototype //var qfy = {} //qfy.__proto__ = codeboy.prototype //2 //this指向空对象 //3 //运行构造方法 //4 //返回对象codeboy.call(qfy)
通过call实现了我们qfy使用了codeboy.prototype里的属性和方法。那我们是不是也可以通过在codeboy里调用call来继承呢。
function stu() { this.name = 'qfy'; } function codeboy() { this.like = 'code'; stu.call(this) } var qfy = new codeboy() console.log(qfy)
可以看到我们的qfy中的this.name = ‘qfy’这就是借构造函数继承,但缺点也看到了,非常消耗内存,因为没有原型共享需要每次执行构造器而且没有原型链无法动态修改,但速度优秀因为不需要从原型链向上查找。没有了原型链就不存在共享的问题,所以上面的问题就可以解决。
介于上面的方法,我们可以将他们给组合起来,我们可以将需要复用的方法写在prototype而把不能共享的数据放在构造函数里通过this来赋值
function stu() { this.name = 'qfy'; this.likes = ['read','code']; } stu.prototype.age = 21; stu.prototype.sayAge = function() { return this.age } function codeboy() { this.like = 'code'; stu.call(this) } codeboy.prototype = new stu() var qfy = new codeboy() var qfy1 = new codeboy() qfy.likes.push('eat') console.log(qfy1.likes)//[ 'read', 'code' ] console.log(qfy1.sayAge())//21
这种方式就是组合继承,是最常用的继承方式,写到这就差不多写完了,还有一些其他不常见的继承方式,大家可以自行百度一下吧。
相关文章推荐
- js继承--apply方法
- js继承的4种方法
- js call方法详细介绍(js 的继承)
- js原型继承的两种方法对比介绍
- js对象中的方法能不能使用原型继承
- 终于搞懂js中cookie的一些处理方法。
- js的继承实现方法
- js call方法详细介绍(js 的继承)
- js使用原型实现继承与new一个新对象的方法
- js继承的实现---object.extend(d,s)方法
- js继承的几种实现方法
- js继承的几种实现方法
- 使用JS中的Call方法实现继承和多重继承
- js call方法详细介绍(js 的继承)
- 用Ext实现js方法的继承,以及扩展Ext组件的开发
- Js Call方法详解(js 的继承)
- js中通过call()和apply()方法实现继承类
- JS 实现 创建类、继承、方法添加、对象克隆、数组封装操作
- Js 的常用方法:页面跳转,Session,类继承
- JS 类的继承改进方法