JS高级(作业域链,闭包,面向对象)
2016-05-29 20:51
423 查看
JS高级(作业域链,闭包,面向对象)
作用域链
定义
变量在当前环境now、内部环境f1、内部深层环境f2/f3....都起作用的现象形成了一个链条,这个链条就称为变量的"作用域链"<script type="text/javascript"> var title="链条“; console.log("now"+title); function f1(){ console.log("f1"+title); function f2(){ console.log("f2"+title); function f3(){ console.log("f3"+title); } f3(); } f2(); } f1(); </script>
作用域链的作用
变量必须“先声明、后使用”函数可以“先使用、后声明”,原因是函数有“预加载”过程(函数声明先于其他执行代码进入内存)。本质还是函数的声明在前,使用在后。
<script type="text/javascript"> f1(); function f1(){ console.log("f1"+title); } </script>
内部环境可以访问外部环境的变量,反之不然
变量的作用域是声明时决定的,而不是运行时
闭包
什么是闭包
闭包就是一个函数,两个函数彼此嵌套,内部函数就是闭包 形成闭包条件是内部函数需要通过return给返回出来.<script type="text/javascript"> function f1(){ var name="tom"; var age=18; function f2(){ console.log("名字:"+name+",年龄:"+age); } return f2; } var ff=f1();//这就是一个闭包,ff与f2共同指向一个function ff();//名字:tom,年龄:age </script>
解释
f1()调用完成后,垃圾回收器会回收name和age,但是因为ff又去指向function,这样function内部的age和name仍然存在,并且与外部变量无关
闭包使用规则
同一个闭包机制可以创建多个闭包函数出来,它们彼此没有联系,都是独立的。 并且每个闭包可以保存自己个性化的信息。<script type="text/javascript"> function f1(){ var name="tom"; var age=18; function f2(){ console.log("名字:"+name+",年龄:"+age); } return f2; } var ff1=f1(); var ff2=f2() var ff3=f3(); </script>
闭包案例
闭包生成数组元素<script type="text/javascript"> var arr=new Array(); for(var i=0;i<4;i++){ arr[i]=function () { console.log(i); return i; } } arr[2](); //4 arr[1](); //4 arr[0](); //4 arr[3](); //4 </script>
使用闭包
<script type="text/javascript"> var arr=new Array(); for(var i=0;i<4;i++){ arr[i]=f1(i); } function f1(n) { function f2() { console.log(n) } return f2; } arr[0](); //0 arr[1](); //1 arr[2](); //2 arr[3](); //3 </script>
闭包事件操作
<script type="text/javascript"> window.onload=function () { var cars=document.getElementsByTagName('li'); //可以利用闭包给每个元素设置独立的函数处理 //并且函数内部也有独特的下标信息供访问 for(var i=0;i<3;i++){ cars[i].onmouseover=over(i); cars[i].onmouseout=out(i); } var col=['red','green','blue']; function over(n) { function f2() { cars .style.backgroundColor=col ; } return f2; } function out(n) { function f2() { cars .style.backgroundColor=""; } return f2; } } </script>
面向对象操作
① 字面量方式创建<script type="text/javascript"> var dog={name:'旺财',age:5,hobby:function () { console.log("看家护院") }}; //对已有成员丰富其对象 dog.color="yellow"; dog['weight']=80; dog.run=function () { console.log("在跑步"); } //访问成员 console.log(dog.name); dog.hobby(); dog['run'](); </script>
② 构造函数创建对象
<script type="text/javascript"> function Animal() { //设置默认成员(通过this引用) this.name="tom"; this.age=6; this.run=function () { console.log("在跑步"); } } var cat=new Animal(); console.log(cat); cat.run(); </script>
③ Object方式创建对象
<script type="text/javascript"> var cat=new Object(); cat.eat="fish"; console.log(cat); </script>
构造函数与普通函数区别
没有区别,就看使用,new就是构造函数,函数()就是普通函数调用。
函数的各种执行方式
① 普通函数调用② 构造函数执行new
③ 作为对象的成员方法执行
④ 通过call和apply执行
call和apply可以明显控制变量污染的风险。
call无需声明新的成员出来,就可以直接使用其他函数或方法
<script type="text/javascript"> var cat={name:"tom",climb:function () { console.log(this.name+"在爬树") }}; var dog={name:"旺财",age:6}; var wolf={name:"灰太狼"}; cat.climb.call(cat); cat.climb.call(dog); </script>
apply()方法与call()方法类似,只是将函数test的所有的参数放在一个数组中而已。即:apply()方法只有两个参数,一个是obj对象,另一个是数组,这个数组中存放的是test函数的所有实参。
总结:是为了动态的改变this的指向
this都是谁
① 在函数/方法里边 代表调用该函数/方法的当前对象② 在事件中,代表元素节点对象
divnode.onclick = function(){ alert(this.value); }
③ 代表window
④ 可以任意代表其他对象
在call和apply使用的时候,可以任意设置被执行函数内部this的代表
获取构造器
构造器:使用什么元素实例化的对象,元素就称为该对象的构造器对象.constructor; //获得构造器
相关文章推荐
- 深入理解PHP之匿名函数
- 最后一次说说闭包
- Ruby中使用Block、Proc、lambda实现闭包
- Lua编程示例(二):面向对象、metatable对表进行扩展
- C#中面向对象编程机制之多态学习笔记
- 浅谈Lua的面向对象特性
- Lua面向对象之类和继承浅析
- LUA中的闭包(closure)浅析
- Lua中的闭包学习笔记
- JavaScript面向对象的两种书写方法以及差别
- 浅谈c# 面向对象之类与对象
- C#面向对象特征的具体实现及作用详解
- C# 面向对象的基本原则
- C#中函数的创建和闭包的理解
- 浅谈对c# 面向对象的理解
- Ruby面向对象编程详解
- C# 面向对象三大特性:封装、继承、多态
- php学习 面向对象 课件第1/2页
- PHP程序61条面向对象分析设计的经验小结
- 收集学习asp.net比较完整的面向对象开发流程