JS继承与闭包及JS实现继承的三种方式


Posted in Javascript onOctober 15, 2017

前  言

在之前的两篇博客中,我们详细探讨了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实现继承的三种方式,希望对大家有所帮助!

Javascript 相关文章推荐
ASP.NET jQuery 实例11 通过使用jQuery validation插件简单实现用户登录页面验证功能
Feb 03 Javascript
使用javascipt---实现二分查找法
Apr 10 Javascript
js实现温度计时间样式代码分享
Aug 21 Javascript
JavaScript实现点击单元格改变背景色的方法
Feb 12 Javascript
jQuery实现ajax的叠加和停止(终止ajax请求)
Aug 08 Javascript
easyui combobox开启搜索自动完成功能的实例代码
Nov 08 Javascript
vue.js 使用v-if v-else发现没有执行解决办法
May 15 Javascript
bootstrap模态框远程示例代码分享
May 22 Javascript
mpvue 页面预加载新增preLoad生命周期的两种方式
Oct 17 Javascript
JavaScript中如何对多维数组(矩阵)去重的实现
Dec 04 Javascript
vuex 多模块时 模块内部的mutation和action的调用方式
Jul 24 Javascript
JS实现可以用键盘方向键控制的动画
Dec 11 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
Oct 15 #Javascript
Vue 2.0入门基础知识之内部指令详解
Oct 15 #Javascript
JS中的多态实例详解
Oct 15 #Javascript
vue跨域解决方法
Oct 15 #Javascript
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
Oct 15 #Javascript
详解 vue.js用法和特性
Oct 15 #Javascript
jQuery实现的页面遮罩层功能示例【测试可用】
Oct 14 #jQuery
You might like
利用discuz实现PHP大文件上传应用实例代码
2008/11/14 PHP
php5.3 不支持 session_register() 此函数已启用的解决方法
2013/11/12 PHP
PHP设计模式之状态模式定义与用法详解
2018/04/02 PHP
php模拟实现斗地主发牌
2020/04/22 PHP
VSCode+PHPstudy配置PHP开发环境的步骤详解
2020/08/20 PHP
Prototype Object对象 学习
2009/07/12 Javascript
js this函数调用无需再次抓获id,name或标签名
2014/03/03 Javascript
Nodejs为什么选择javascript为载体语言
2015/01/13 NodeJs
jQuery设置和移除文本框默认值的方法
2015/03/09 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
Javascript实现单例模式
2016/01/24 Javascript
Vue.js组件tabs实现选项卡切换效果
2016/12/01 Javascript
js处理层级数据结构的方法小结
2017/01/17 Javascript
JS中静态页面实现微信分享功能
2017/02/06 Javascript
微信小程序 引用其他js文件实现代码
2017/02/22 Javascript
基于JS实现带动画效果的流程进度条
2018/06/01 Javascript
ES6入门教程之变量的解构赋值详解
2019/04/13 Javascript
微信小程序监听用户登录事件的实现方法
2019/11/11 Javascript
[01:02:04]EG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
python中文分词,使用结巴分词对python进行分词(实例讲解)
2017/11/14 Python
解决pyinstaller打包exe文件出现命令窗口一闪而过的问题
2018/10/31 Python
解决Pycharm界面的子窗口不见了的问题
2019/01/17 Python
75条笑死人的知乎神回复,用60行代码就爬完了
2019/05/06 Python
分享8点超级有用的Python编程建议(推荐)
2019/10/13 Python
python单向循环链表原理与实现方法示例
2019/12/03 Python
python 微信好友特征数据分析及可视化
2020/01/07 Python
一款纯css3实现简单的checkbox复选框和radio单选框
2014/11/05 HTML / CSS
德国箱包网上商店:koffer24.de
2016/07/27 全球购物
路易威登和香奈儿手袋:LuxeDH
2017/01/12 全球购物
Ado与Ado.net的相同与不同
2014/12/08 面试题
《中彩那天》教学反思
2014/02/22 职场文书
保密工作实施方案
2014/02/24 职场文书
旅游文化节策划方案
2014/06/06 职场文书
KTV员工管理制度
2015/08/06 职场文书
2016公务员年度考核评语
2015/12/01 职场文书
2017寒假社会实践心得体会范文
2016/01/14 职场文书