前 言
在之前的两篇博客中,我们详细探讨了JavaScript OOP中的各种知识点(JS OOP基础与JS 中This指向详解 、 成员属性、静态属性、原型属性与JS原型链)。今天我们来继续探讨剩余的内容吧。
我们都知道,面向对象的三大特征——封装、继承、多态。 封装无非就是属性和方法的私有化,所以我们JS中提供了私有属性和私有方法。 而JS中并没有多态,因此我们说JS是一门基于对象的语言,而非面向对象的语言。 那么,面向对象三大特征中,在JS中最重要的就是继承了。
一、继承的基本概念
使用一个子类继承另一个父类,子类可以自动拥有父类的属性和方法。
>继承的两方,发生在两个类之间。
所以,所谓的继承,无非就是让子类,拥有父类的所有属性和方法。那么,在JS中,我们要模拟实现这一步,有三种常用的方法可以实现。
分别是:扩展Object的prototype实现继承、使用call和apply实现继承、使用原型实现继承。
二、扩展Object的prototype实现继承
扩展Object实现继承的本质,是我们自己写了一个方法,将父类的所有属性和方法通过遍历循环,逐个复制给子类。
详细步骤如下:
1:定义父类
functionParent(){}
2:定义子类
funtion Son(){}
3:通过原型给Object对象添加一个扩展方法。
Object.prototype.customExtend =function(parObj){ for(variinparObj){//通过for-in循环,把父类的所有属性方法,赋值给自己 this[i] =parObj[i]; } }
4:子类对象调用扩展方法
Son.customExtend(Parent);
三、使用call和apply实现继承
首先,要使用这种方式显示继承,我们再来回顾一下call和apply两个函数的作用:
call和apply:通过函数名调用方法,强行将函数中的this指向某个对象;
call写法:func.call(func的this指向的obj,参数1,参数2...);
apply写法:func.apply(func的this指向的obj,[参数1,参数2...]);
那么,我们使用这两个函数实现继承的思路就是:在子类中,使用父类函数调用call或apply,并将父类的this,强行绑定为子类的this。 那这样,父类绑定在this上的属性和方法,不就顺利成章的绑定到子类的this上了吗?
详细步骤如下:
1:定义父类
funtion Parent(){}
2:定义子类
functionSon(){}
3:在子类中通过call方法或者apply方法去调用父类。
functionSon(){ Parent.call(this,....);//将父类函数中的this,强行绑定为子类的this}
四、使用原型实现继承
使用原型实现继承,是比较简单而且比较好理解的一种,就是将子类的prototype指向父类的对象就可以啦。
详细步骤如下:
1:定义父类
functionParent(){}
2:定义子类
functionSon(){}
3:把在子类对象的原型对象声明为父类的实例。
Son.prototype =newParent();
五、闭包
要理解闭包,首先,我们要了解一下JS中的作用域:
1、JS中的作用域
全局变量:函数外声明的变量
局部变量:函数内声明的变量
在JS中,函数为唯一的局部作用域,而if、for等其他{}没有自己的作用域
所以,函数外不能访问局部变量。其实,变量在函数执行完毕以后,占用的内存就会被释放。
2、闭包
在概述中,我刚刚提到,面向对象的三大特征中的“封装”,我们可以用函数的私有属性来实现。这个私有属性,其实也就是局部变量。
但是我们都知道,封装是限制外部的访问,并不是直接拒绝外部的访问,那么我们在函数中私有的属性,怎么才能在外部访问呢?答案就是闭包!
JS中,提供了一种"闭包"的概念:在函数内部,定义一个子函数,可以用子函数访问父函数的私有变量。执行完操作以后,将子函数通过return返回。
代码示例:
functionfunc2(){varnum = 1;functionfunc3(){varsum = num+10; alert(sum); }returnfunc3; }varf =func2(); f();
3、闭包的作用:
① 访问函数的私有变量;
② 让函数的变量始终存在于内存中,而不被释放。
4、闭包的典型应用
我们来做这样一个功能:页面中有6个li,要求实现点击每个li,弹出这个li对应的序号。
HTML代码很简单:
那JS代码呢?我觉得很大一部分同学会这样写:
varlis = document.getElementsByTagName("li");for(vari=0;i lis[i].onclick=function(){ alert("您/点击了第"+i+"个li!"); }
那么,这样对吗?不对!!!我们来分析一下:页面加载的时候,JS代码会全部执行,也就是上面的for循环在页面加载完就已经执行完了!那,这个i就已经变成了lis.length。也就是说,你在点击li的时候,无论点击第几个,弹出的都是lis.length。
那么,我们应该怎么修改呢?看代码!
varlis = document.getElementsByTagName("li");for(vari=0;i lis[j].onclick=function(){ alert("您/点击了第"+j+"个li!"); } }(); }
区别在哪?明眼人一眼就看穿我们在for循环外面嵌套了一层自执行函数!这种函数套函数的形式,就形成了闭包!
那作用呢?我们刚才强调,闭包的自执行函数会有自己的作用域。在函数里面的代码没有执行的时候,自执行函数中的j是不会被释放掉的!
也就是说,循环转了6次!生成了6个独立的函数空间,每个空间中有自己独立的j变量,所以最终不会出现所有li点击都是lis.length的情况!
总结
以上所述是小编给大家介绍的JS继承与闭包及JS实现继承的三种方式,希望对大家有所帮助!
js,继承,闭包
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]