在前面说对象的时候已经提到了函数对象,对函数的定义参数的传递包括通过argumentd.callee实现递归。这篇博客我会继续深入讲解js中的函数表达式。

一,闭包

关于闭包的概念,可以先看看http://www.jb51.net/article/24101.htm,闭包是指有权访问另一个函数作用域中的变量的函数。在刚刚这个链接中对闭包的用法说的很清楚了,我感觉我没法说得比这个文章更简单更清楚了。但是,还是有几点很重要的东西这个文章没讲的,我补充一下。

1,变量

闭包只能取得包含函数中任何变量的最后一个值,举例就是

            function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(){return i;};}return result;}var funcs = createFunctions();//every function outputs 10for (var i=0; i < funcs.length; i++){document.write(funcs[i]() + "<br />");  //输出10个10}

但是,我们可以通过创建另一个匿名函数强制让闭包的行为符合预期

            function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(num){return function(){return num;};}(i);}return result;}var funcs = createFunctions();//every function outputs 10for (var i=0; i < funcs.length; i++){document.write(funcs[i]() + "<br />");}

原理就是在for循环里面增加一个匿名函数,然后把这个匿名函数的值返回给数组。在循环内部,在调用每个匿名函数时,就形成了闭包,i的值得到了保存并且存到了数组里面。

2,this对象

在闭包使用this对象可能导致一些问题:匿名函数的执行环境具有全局性,那么看例子

        var name = "The Window";var object = {name : "My Object",getNameFunc : function(){return function(){return this.name;};}};alert(object.getNameFunc()());  //"The Window"

有一种比较蠢的办法解决,就是先把包含作用域保存到另一个变量:

            var name = "The Window";var object = {name : "My Object",getNameFunc : function(){var that = this;return function(){return that.name;};}};alert(object.getNameFunc()());  //"MyObject"

3,内存泄露

实际上,闭包保存包含函数作用域的变量利用的就是前面说过的垃圾回收机制,所有被引用的变量都不会被回收,但是总是不回收势必导致一个问题,内存泄漏。解决办法也很简单,很普通的方法,释放该变量就行了。用完之后赋值null。

二,模仿块级作用域
前面说过了,js是没有块级作用域的。但是很多情况下我们需要一个私有作用域,这种情况下可以利用函数作用域来实现。先定义一个匿名函数,然后马上执行这个函数。

            function outputNumbers(count){(function () {for (var i=0; i < count; i++){alert(i);}})();alert(i);   //causes an error}

值得注意的是,函数外部的小括号非常重要,加上这个小括号才能把函数声明转化成函数表达式,只有函数表达式才能在后面接小括号立即执行。

三,私有变量
函数内部的变量可以通过闭包的方式保存在内存中,而外部作用域是无法直接修改的,除非在函数内部增加修改这些变量的函数接口,这些接口就是特权方法。只有通过特权方法才能修改这些私有变量。

            function Person(name){this.getName = function(){return name;};this.setName = function (value) {name = value;};}var person = new Person("Nicholas");alert(person.getName());   //"Nicholas"person.setName("Greg");alert(person.getName());   //"Greg"

不过,在构造函数中定义特权方法让代码复用性很低,原因和前面说过的创建对象一样,构造函数每次实例时都会创建同样的一组新方法。下面介绍新的方法。

1,静态私有变量

之前是通过原型对象解决的,这次也可以一样。

            (function(){var name = "";Person = function(value){                name = value;                };Person.prototype.getName = function(){return name;};Person.prototype.setName = function (value){name = value;};})();var person1 = new Person("Nicholas");alert(person1.getName());   //"Nicholas"alert(person1.name);alert(person1.getName());   //"Greg"var person2 = new Person("Michael");alert(person1.getName());   //"Michael"alert(person2.getName());   //"Michael"

2.模块模式

没搞明白,以后再说。

[Javascript 高级程序设计]学习心得记录10 js函数表达式相关推荐

  1. [Javascript 高级程序设计]学习心得记录11 js的BOM

    BOM(浏览器对象模型)是web中js的核心,而BOM的核心对象就是window对象.在浏览器中,window对象有双重角色,它既是通过js访问浏览器的一个接口,又是规定的Global对象.此外,还有 ...

  2. [Javascript 高级程序设计]学习心得记录9 js面向对象

    感觉最难的部分就是面向对象了,大学期间学习的是面向过程的c/c++,工作之后也没有深入了解过面向对象,通过这次的学习和回顾,也算是对面向对象有了新的认识.不过,就我在书上学到了结合个人理解随便说说,很 ...

  3. [Javascript 高级程序设计]学习心得记录 函数参数传递与引用

    最近开始啃js的红宝书:<Javascript 高级程序设计>,偶有心得,记录一下. 先上代码 function howManyArgs() {alert(arguments.length ...

  4. [Javascript 高级程序设计]学习心得记录2 Javascript的垃圾回收机制

    Javascript 是自动垃圾收集机制,不需要像c/c++的开发人员一样担心内存泄漏问题.这种垃圾收集机制通过找出那些不再使用的变量,释放其占用的内存从而达到垃圾回收的效果.而如何如何找出那些不再使 ...

  5. [Javascript 高级程序设计]学习心得记录6 变量和作用域

    js的变量和其他语言的变量区别还是挺大的,它只是在特定时间用于保存特定值的一个名字而已,js的变量高度灵活,同时又很容易出问题,需要专门学习. 一,基本类型和引用类型的值 基本类型值指数据的五种基本类 ...

  6. [Javascript 高级程序设计]学习心得记录3 根据对象数组的属性进行排序

    配合sort(),将排序的标准属性传入排序函数,在进行排序的时候将该属性取出来就行了. function createComparisonFunction(propertyName) {return ...

  7. JavaScript高级程序设计学习笔记(三)

    分享一下第五章(引用类型)的笔记,内容比较多,我拆成了两部分,今天这部分是关于Object.Array.Date和RegExp类型的. 以下的笔记是书上一些我以前学习的时候,没有太重视的js基础知识, ...

  8. javascript高级程序设计学习笔记

    javascript高级程序设计,当枕头书已经好久了~zz  现在觉得自己在js的开发上遇到了一些瓶颈,归根究底还是基础太薄弱,所以重新刷一遍js高程希望有更新的认识. 一.javascript简介 ...

  9. javascript高级程序设计学习之数值转换 |Number(),parseInt(),parseFloat()

    2019独角兽企业重金招聘Python工程师标准>>> 将非数值转换成数值的函数有三个:Number(),parseInt(),parseFloat(); 小记tip:Number( ...

最新文章

  1. nginx中301和302重定向之间的区别
  2. Javascript_初学第1天
  3. 19 个 JavaScript 常用的简写技术
  4. wxWidgets 示例演示 wxWrapSizer 的使用
  5. Cacti添加IO模板并监控磁盘IO
  6. td外边加div为啥不隐藏_过年炸油饼注意了,秘制配方比例教给你,柔软不吸油,放凉了不硬...
  7. 活动报名 | 2017无人驾驶智能车Hackathon挑战赛
  8. Qt实现Areo效果_vortex_新浪博客
  9. 智慧楼宇物联网公司En-trak获Pre-A 轮融资
  10. SpringBoot开发案例之拦截器注入Bean
  11. hdu 1978 How many ways(dp)
  12. 16_多易教育之《yiee数据运营系统》用户画像-标签体系设计篇
  13. SDN是什么东东???
  14. 播放音乐的html代码,音乐播放器-html代码
  15. debian系统简单介绍
  16. 合并Windows系统镜像教程(Win 7+win 8.1 合盘)
  17. 开源在线客服系统源码(支持PC/H5/公众号/小程序)基于golang的网页在线客服系统...
  18. 完全手册-MATLAB使用详解:基础、开发及工程应用
  19. VBA中的颜色,colorIndex 或color 或backcolor
  20. 历年计算机office试题及答案,历年计算机二级MS Office真题及答案

热门文章

  1. 梦想照进现实|CSDN 实体奖牌 第五期
  2. 融合注意力机制和Bi-LSTM的旅游评价情感分析模型
  3. 01: 网络参考模型 、 数据封装与传输 、 数制与数制转换 、 IP地址与子网掩码
  4. Java 移位、逻辑运算符详解(~史上最全|吹牛逼)
  5. 7-2 531 字符串_小写变大写
  6. 干货|如何写好项目进度报告
  7. 【研究总结】基于出租车GPS轨迹数据的相关研究
  8. 钟汉良日记:改变心态了,回武平待3年
  9. 带有富文本数据如何导出word文档(使用mht模板)
  10. EcShop常用 促销活动表结构