JavaScript中闭包的使用和各种继承介绍
一、什么是闭包?
//1、for循环之中:
// for循环之中的i变量会因为for的循环次数被覆盖,所以在for循环内部存在函数时,而且这个函数内会调用i变量,这种情况下就需要用到闭包。 for (var i = 0; i < 10; i++) {
console.log(i); //可以访问到每次的i
} // 必须满足两个条件:
// 1.在for循环内存在函数
// 2.函数内会调用这个变量 var ali = document.getElementsByTagName("li");
for(var i=0;i<10;i++){
ali[i].onclick = function(){
console.log(i); //在函数内部就无法访问到外部变量
}
} // 如何形成闭包
var ali = document.getElementsByTagName("li");
for(var i=0;i<10;i++){
(function(a){
ali[a].onclick = function(){
console.log(a);
}
})(i)
}
// 一旦内部函数调用外部函数的局部变量,那么这个时候,这个局部变量就会变成内部函数的私有变量 // 2、当需要给setTimeout的回调函数传参时:
setTimeout(function (a){
console.log(a); //两秒后,undefined
}, 2000);
// 或者
setTimeout(fn(10), 2000);
function fn(a){
console.log(a); //没有延迟,直接打印10
} // 怎么使用闭包: function fn(a){
return function(){
console.log(a); //两秒后,10
}
}
var f = fn(10);
setTimeout(f, 2000);
三、闭包的特点:
(1)闭包是将函数内部和函数外部连接起来的桥梁.
(2)可以读取函数内部的变量。
(3)让这些变量的值,始终保存在内存中,不会在调用结束后被系统回收。
(4)避免全局变量命名空间的污染。
(5)内存消耗很大,不能滥用。
(6)闭包会在父函数外部,改变父函数内部变量的值。
四、构造函数继承:
// 在构造函数中,同样属于两个新创建的函数,也是不相等的
function Fn(name){
this.name = name;
this.show = function(){
alert(this.name);
}
}
var obj1 = new Fn("AAA");
var obj2 = new Fn("BBB");
obj1.show()
obj2.show()
// 此时,任何一个new出来的实例上都有了show方法,可以视为最基础的继承。
五、js中的call和apply继承:
function Father(skill){
this.skill = skill;
this.show = function(){
alert("我会"+this.skill);
}
}
function Son(abc){
//这里的this指向函数Son的实例化对象
//将Father里面的this改变成指向Son的实例化对象,当相遇将father里面所有的属性和方法都复制到了son身上
//Father.call(this,abc);//继承结束,call适合固定参数的继承
//Father.apply(this,arguments);//继承结束,apply适合不定参数的继承
}
var f = new Father("绝世木匠”);
var s = new Son("一般木匠");
f.show()
s.show();
// 优点:
// 创建子类实例时,可以向父类的构造器传参;
// 缺点:
// 只能继承构造器中定义的属性和方法,不能继承原型上定义的属性和方法
六、js中prototype的概念:
(1)prototype是原型对象
(2)指针 constructor 表示当前函数属于谁,用来指向当前原型所属的函数
(3)原型指针 [[prototype]] __proto__ 相当于一根原型指针,指向当前对象的“父级”
(4)可以在当前函数的原型身上添加各种属性和方法,以供使用
(5)JS中万物皆对象,所有内容的指针终点都指向Object
七、原型链继承:
// 方法一:
Son.prototype = new Father();
//创建一个函数Father,用来做原始对象
function Father(){
this.skill = "铁匠"
};
Father.prototype.show = function(){
console.log(this.skill)
}
//创建一个函数Son,准备继承Father的原型
function Son(){};
//将Son点原型,赋值为一个指针,指向Father的原型
Son.prototype = new Father(); //此时就可以通过执行new Son()获取到从构造函数Father上继承过来属性和方法
var s = new Son()
s.show(); //铁匠 // 优点:
// 1.可以访问父类原型上的方法和属性
// 2.简单方便,易于实现 // 缺点:
// 1.创建子类实例时,无法向父类的构造器传参 // 方法二:
//创建一个函数Father,用来做原始对象
function Father(){
this.skill = "铁匠";
};
Father.prototype.show = function(){
console.log("hello world")
}
//创建一个函数Son,准备继承Father的原型
function Son(){};
//将Son的原型,设置为Father的原型
//Son.prototype = Father.prototype;
//但是这种拷贝方式为对象的浅拷贝,一旦后期修改Son原型上的方法,会影响到Father的原型
//需采用对象的深拷贝方法
for(var i in Father.prototype){
Son.prototype[i] = Father.prototype[i];
}
Son.prototype.show = function(){
console.log("这是子类修改之后的show方法")
}
var f = new Father()
f.show()
var s = new Son()
s.show(); // 优点:
// 完全将父类原型上的方法和属性拷贝到子类原型 // 缺点:
// 只能继承原型上的方法和属性,构造函数无法传参和继承
八、混合继承:
// 特点:
// 使用call或apply继承父类的构造器中的内容,使用原型继承,继承父类的原型
function Father(skill,id){
this.skill = skill;
this.id = id;
}
Father.prototype.show = function(){
alert("我是father,这是我的技能"+this.skill);
} function Son(){
Father.apply(this,arguments);
}
//如果不做Son的原型继承Father的原型,此时会报错:son.show is not a function
for(var i in Father.prototype){
Son.prototype[i] = Father.prototype[i];
}
//因为,如果不让Son的原型等于Father的原型,Son使用apply是继承不到原型上的方法
Son.prototype.show = function(){
alert("我是son,这是我的技能"+this.skill);
}
var f = new Father("专家级铁匠","father");
var s = new Son("熟练级铁匠","son");
f.show();
s.show();
九、ES6中class的继承:
class Father{
constructor(){
}
show(){
}
} class Son extends Father{
constructor(){
super()
}
show(){
}
}
十、原型对象相关概念解析:

JavaScript中闭包的使用和各种继承介绍的更多相关文章
- 在Javascript中闭包(Closure)
在Javascript中闭包(Closure) 什么是闭包 “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. ...
- javascript中闭包最简单的简绍
javascript中闭包是什么 JavaScript 变量可以是局部变量或全局变量.私有变量可以用到闭包.闭包就是将函数内部和函数外部连接起来的一座桥梁. 函数的闭包使用场景:比如我们想要一个函数来 ...
- 在JavaScript中闭包的作用和简单的用法
在JavaScript中闭包的作用和简单的用法 一.闭包的简介 作用域链:在js中只有函数有作用域的概念,由于函数内能访问函数外部的数据,而函数外部不能访问函数内部的数据,由上述形成一种作用域访问的链 ...
- JavaScript中闭包之浅析解读
JavaScript中的闭包真心是一个老生常谈的问题了,最近面试也是一直问到,我自己的表述能力又不能完全支撑起来,真是抓狂.在回来的路上,我突然想到了一个很简单的事情,其实我们在做项目时候,其实就经常 ...
- 关于javascript中闭包的理解
闭包就是能够读取其他函数内部变量的函数. 在javascript中,只有函数内部的子函数可以读取局部变量,因此,我理解闭包就是定义在一个函数内部的函数. 例子: var f1 = function() ...
- 浅谈JavaScript中闭包
引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...
- javascript中闭包的概念
这个是每个前端工程师绕不开的一个问题,网上各种资料很多,整个春节,我仔细研读了红皮经典中关于这一块的注释,加深了对这一块的理解. 有好几个概念需要重申一下.以下都是我的理解: 1. 闭包是javasc ...
- Javascript中闭包的作用域链
作用域定义了在当前上下文中能够被访问到的成员,在Javascript中分为全局作用域和函数作用域,通过函数嵌套可以实现嵌套作用域. 闭包一般发生在嵌套作用域中.闭包是JavaScript最强大的特性之 ...
- JavaScript中闭包实现的私有属性的getter()和setter()方法
注意: 以下的输出都在浏览器的控制台中 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
随机推荐
- ACM-ICPC 2017 Asia Urumqi:A. Coins(DP) 组合数学
Alice and Bob are playing a simple game. They line up a row of nn identical coins, all with the head ...
- 题目1362:左旋转字符串(Move!Move!!Move!!!)
题目1362:左旋转字符串(Move!Move!!Move!!!) 时间限制:2 秒 内存限制:32 兆 特殊判题:否 提交:2306 解决:961 题目描述: 汇编语言中有一种移位指令叫做循环左移( ...
- Codeforces Round #383 (Div. 2)D. Arpa's weak amphitheater and Mehrdad's valuable Hoses(dp背包+并查集)
题目链接 :http://codeforces.com/contest/742/problem/D 题意:给你n个女人的信息重量w和美丽度b,再给你m个关系,要求邀请的女人总重量不超过w 而且如果邀请 ...
- 林大妈的JavaScript进阶知识(三):HTML5 History API
HTML5中新增了History API,它用于管理浏览器路由跳转的一个url栈.History是window对象的一部分,它也是一个对象,因此称它是BOM(类似DOM,Browser Object ...
- Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.apache.catalina.connector.CoyoteWriter and no properties discovered to create BeanSerializer
一.什么是序列化In computer science, in the context of data storage, serialization is the process of transla ...
- 几个Python爬虫工具介绍
Request Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用 上面一句话 出自Requests官方文档的第一句,从而奠定了其逗逼的文档风格.类似的还有: 警告: ...
- 【Spring】 AOP Base
1. AOP概述 2. AOP的术语: 3. AOP底层原理 4. Spring 中的AOP 4.1 概述 4.2 分类 4.3 Spring的传统AOP 针对所有方法的增强:(不带有切点的切面) 带 ...
- 【Offer】[6] 【从尾到头打印链表】
题目描述 思路分析 Java代码 代码链接 题目描述 从尾到头打印链表,将其添加到ArrayList当中输出 思路分析 递归的思路 利用栈 Java代码 public class Offer006 { ...
- win10 解决端口被占用
查看端口 netstat -aon|findstr "端口" 通过PID查找应用程序 tasklist|findstr "PID" 关闭进程 taskkill ...
- Unity3D_06_根据Transform、GameObject和Tag获取子对象集合
导引: 因为项目中难免要多次进行获取子对象或者子对象的集合,所以写一个单独的类,用来做这些操作.然后再实际的项目中,只需要使用 transform 或者 gameobject 调用这些方法就可以快速的 ...