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 相关文章推荐
在页面上点击任一链接时触发一个事件的代码
Apr 07 Javascript
jQuery获取Select选择的Text和Value(详细汇总)
Jan 25 Javascript
javascript 实现子父窗体互相传值的简单实例
Feb 17 Javascript
javascript实现禁止鼠标滚轮事件
Jul 24 Javascript
jquery使用ul模拟select实现表单美化的方法
Aug 18 Javascript
jQuery基于ajax()使用serialize()提交form数据的方法
Dec 08 Javascript
Javascript将数值转换为金额格式(分隔千分位和自动增加小数点)
Jun 22 Javascript
vue 根据数组中某一项的值进行排序的方法
Aug 30 Javascript
BootstrapValidator验证用户名已存在(ajax)
Nov 08 Javascript
Javascript如何递归遍历本地文件夹
Aug 06 Javascript
如何使用 JavaScript 操作浏览器历史记录 API
Nov 24 Javascript
ECharts transform数据转换和dataZoom在项目中使用
Dec 24 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
Laravel重写用户登录简单示例
2016/10/08 PHP
PHP中STDCLASS用法实例分析
2016/11/11 PHP
phpinfo无法显示的原因及解决办法
2019/02/15 PHP
PHP判断是否是微信打开还是浏览器打开的方法
2019/02/27 PHP
javascript中对Attr(dom中属性)的操作示例讲解
2013/12/02 Javascript
jquery form表单序列化为对象的示例代码
2014/03/05 Javascript
Jquery对select的增、删、改、查操作
2015/02/06 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
webpack入门+react环境配置
2017/02/08 Javascript
Nodejs 和Session 原理及实战技巧小结
2017/08/25 NodeJs
vue 框架下自定义滚动条(easyscroll)实现方法
2019/08/29 Javascript
node事件循环和process模块实例分析
2020/02/14 Javascript
利用Vue的v-for和v-bind实现列表颜色切换
2020/07/17 Javascript
[32:30]夜魇凡尔赛茶话会 第一期01:谁是卧底
2021/03/11 DOTA
python3模拟百度登录并实现百度贴吧签到示例分享(百度贴吧自动签到)
2014/02/24 Python
深入解析Python中的集合类型操作符
2015/08/19 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
Python面向对象基础入门之编码细节与注意事项
2018/12/11 Python
Python Pywavelet 小波阈值实例
2019/01/09 Python
如何使用Python脚本实现文件拷贝
2019/11/20 Python
python实现用类读取文件数据并计算矩形面积
2020/01/18 Python
python 非线性规划方式(scipy.optimize.minimize)
2020/02/11 Python
HTML5文档结构标签
2017/04/21 HTML / CSS
HTML5+Canvas+CSS3实现齐天大圣孙悟空腾云驾雾效果
2016/04/26 HTML / CSS
Html5页面点击遮罩层背景关闭遮罩层
2020/11/30 HTML / CSS
Timberland法国官网:购买靴子、鞋子、衣服、夹克和配饰
2019/11/30 全球购物
意大利领先的奢侈品在线时装零售商:MCLABELS
2020/10/13 全球购物
利用promise及参数解构封装ajax请求的方法
2021/03/24 Javascript
网络编辑职责
2014/03/01 职场文书
小学生期末评语
2014/04/21 职场文书
幼儿园教师师德师风演讲稿:爱我所爱 无悔青春
2014/09/10 职场文书
领导班子民主生活会整改措施(工商局)
2014/09/21 职场文书
小学生运动会通讯稿
2014/09/23 职场文书
红旗渠导游词
2015/02/09 职场文书
百家讲坛观后感
2015/06/12 职场文书
创业计划书之珠宝饰品
2019/08/26 职场文书