函数声明

特点:函数声明提升(执行代码之前解析器会先读取函数声明,并使其在执行任何代码之前可用,意味着可以把函数声明放在调用语句之后)

  1. function functionName(arg0,arg1) {
  2. //do something
  3. }

函数表达式

特点:无提升(须等到解析器执行到它所在的代码行才会真正被解析执行)

1.最常见-匿名函数

  1. var functionName = function() {
  2. //do something
  3. };

2.命名函数表达式

  1. var functionName = (function f() {
  2. //do something
  3. });

一、递归

1.arguments.callee

一个指向正在执行的函数的指针,代替函数名

  1. function factorial(num) {
  2. if(num <= 1){
  3. return 1;
  4. } else {
  5. return num * arguments.callee(num-1);
  6. }
  7. }

2.命名函数表达式

严格模式下arguments.callee报错,可用命名函数表达式代替

  1. var factorial = (function f(num) {
  2. if(num <= 1){
  3. return 1;
  4. } else {
  5. return num * f(num-1);
  6. }
  7. });

二、闭包

闭包是指有权访问另一个函数作用域中变量的函数

创建闭包最常见的方式是在一个函数内部创建另外一个函数

由于闭包会携带包含它的函数的作用域,因此过度使用闭包可能会导致内存占用过多

闭包只能取得包含函数中任何变量的最后一个值(不是很理解)

  1. //错误栗子
  2. function createFunc() {
  3. var result = new Array();
  4. for(var i=0; i < 10; i++) {
  5. result[i] = function() {
  6. return i; //闭包,均返回i的最后一个值10
  7. };
  8. }
  9. return result;
  10. }
  11. //正确栗子
  12. function createFunc() {
  13. var result = new Array();
  14. for(var i=0; i < 10; i++) {
  15. result[i] = function(num){
  16. return function() {
  17. return num;
  18. };
  19. }(i); //立即执行,传递当前值给参数num
  20. }
  21. return result;
  22. }

关于this:匿名函数的执行环境具有全局性,其this通常指向window

IE9-:内存泄露-如果闭包的作用域链保存了一个HTML元素,则该元素无法被销毁

  1. //错误栗子
  2. function asignHandler() {
  3. var element = document.getElementById('someElem');
  4. element.onclick = function = () { //闭包
  5. alert(element.id);
  6. };
  7. }
  8. //正确栗子
  9. function asignHandler() {
  10. var element = document.getElementById('someElem');
  11. var id = element.id; //保存副本
  12. element.onclick = function = () { //闭包
  13. alert(id); //弹出副本
  14. };
  15. element = null; //解除引用,回收内存
  16. }

三、模仿块级作用域

JavaScript无块级作用域的概念

  1. //无块级作用域
  2. function outputNumbers(count) {
  3. for(var i=0; i < count; i++) { //变量i在outputNumbers()的作用域中
  4. alert(i);
  5. }
  6. alert(i); //在for外仍可访问变量i
  7. }
  8. //模仿块级作用域
  9. function outputNumbers(count) {
  10. (function() {
  11. //这里是块级作用域,闭包,可访问外部变量
  12. for(var i=0; i < count; i++) {
  13. alert(i);
  14. }
  15. })();
  16. alert(i); //报错!
  17. }
  18. //运用:避免全局变量和函数
  19. //无指向匿名函数的引用,故能减少闭包占用的内存,只要函数执行完毕即可销毁其作用域链
  20. //把以下代码放在全局作用域中
  21. (function() {
  22. var now = new Date(); //now为匿名函数的局部变量
  23. if(now.getMonth() == 0 && now.getDate() == 1) {
  24. alert('Happy new year!');
  25. }
  26. })();

四、私有变量与特权方法

1.在构造函数中定义特权方法

特点:每个实例都会创建同样一组新方法

  1. function Person(name) { //name为私有变量
  2. //两个特权方法
  3. this.getName() = function() {
  4. return name;
  5. };
  6. this.setName() = function(value) {
  7. name = value;
  8. };
  9. }

2.在私有作用域中定义私有变量和函数(静态私有变量)

特点:私有变量和函数是每个实例共享的

  1. (function() {
  2. var name = ''; //共享的,静态私有变量,
  3. Person = function(value) {
  4. name = value;
  5. };
  6. Person.prototype.getName = function() {
  7. return name;
  8. };
  9. Person.prototype.setName = function(value) {
  10. name = value; //在一个实例上调用setName()会影响所有实例的name
  11. };
  12. })();

3.模块模式

为单例(只有一个实例的对象)创建私有变量和特权方法

适用于需要对单例进行某些数据的初始化,同时又要维护其私有变量的情形

  1. var application = function() {
  2. //私有变量和函数
  3. var components = new Array();
  4. //初始化
  5. component.push(new BaseComponent()); //向数组添加了一个BaseComponent(无关紧要)的新实例
  6. //特权方法
  7. return {
  8. getComponentCount : function() {
  9. return components.length;
  10. },
  11. registerComponent : function(component) {
  12. if(typeof component == 'object') {
  13. components.push(component);
  14. }
  15. }
  16. };
  17. }();

4.增强模块模式(还没闹明白,明白后再补充)

本书其它章节中关于函数的内容

使用不带圆括号的函数名是访问函数指针,而非调用函数!

1.return

函数会在执行完return语句后停止并立即退出,因此,位于return语句之后的任何代码都永远不会执行

return语句也可以无返回值,函数停止执行后将返回undefined

2.参数

函数内可通过arguments对象(函数的两个特殊对象之一)来访问参数数组(但arguments并非Array的实例),可与命名参数一起使用

arguments与对应命名参数的内存空间是分别独立的,但它们的值会同步

参数并非必须命名

未传递值的命名参数将自动赋予undefined

arguments.callee:是一个指针,指向拥有这个arguments对象的函数(消除紧密耦合)

4.this(函数的两个特殊对象之一)

引用的是函数据以执行的环境对象

3.没有重载

两个名字相同的函数,该名字只属于后定义的函数

4.作为值的函数

ECMAscript中的函数名本身就是变量,所以函数可以作为值来使用

-可以像传递参数一样把一个函数传递给另一个函数(无圆括号)

-可以将一个函数作为另一个函数的结果返回

5.函数的内部属性

arguments对象

this对象

caller属性:指向调用当前函数的函数,如果是在全局中调用当前函数则其值为null,可通过arguments.callee.caller实现更松散的耦合

6.函数的属性和方法

length属性:表示函数希望接受的命名参数的个数

prototype属性:ECMAscript5不可枚举

*设置this的值的方法,能扩充函数的作用域(非继承方法)

-apply(作用域,[参数])

-call(作用域,参数1,参数2,参数3)

bind():创建一个实例,其this值绑定到bind()的参数

*继承方法

toLocaleString()、toString()、valueOf()

以上均返回函数的代码

函数表达式(JavaScript高程笔记)的更多相关文章

  1. JAVASCRIPT高程笔记-------第 七章 函数表达式

    7.1递归 经典递归例子 function factorial(num){ if(num <= 1){ return 1; }else{ return num * factorial(num - ...

  2. JAVASCRIPT高程笔记-------第五章 引用类型

    一.Object类型 1.1创建方式 ①new关键字 : var person = new Oject(); ②给定直接量: var person = { name : "zhangsan& ...

  3. DOM(JavaScript高程笔记)

    一.节点层次 1.Node类型 if (someNode.nodeType == 1){ // 适用于所有浏览器 alert("Node is an element."); } N ...

  4. javaScript高程笔记--最佳实践

    1.可维护性 <1>什么是可维护的代码 (1)可理解性 (2)直观性 (3)可适应性 (4)可扩展性 (5)可调试性 <2>代码约定 (1)可读性---适当的进行注释[函数和方 ...

  5. JAVASCRIPT高程笔记-------JSON与AJAX

    json对象——语法 简单值:与JS相同语法,可以是字符串,数值,布尔值,null:但不支持undefined 对象: 复杂数据类型,表示一组有序的键值对,键值对的值可以是简单数据,也可以是复杂数据 ...

  6. JAVASCRIPT高程笔记-------第十章 DOM对象

    10.1.1 node类型 --除IE外 所有浏览器都可以访问到这个类型 :JS中所有的节点类型都继承自Node类型 nodeName 与nodeValue  如果是一个元素 那么nodeName中保 ...

  7. javascript高程笔记-------第四章 变量、作用域和内存问题

    首先JavaScript中的变量分为基本类型和引用类型. 基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象. 1.参数传递 javascript中所有参数的传递都是值传 ...

  8. BOM(JavaScript高程笔记)

    再次编辑于20160115 一.window对象 双重角色 JS访问浏览器窗口的接口 ECAMAscript规定的Global对象 1.全局作用域 所有在全局作用域中声明的变量.函数都会变成windo ...

  9. javascript高程笔记:逻辑与和逻辑或

    逻辑与和或 逻辑与 当 && 前后两个操作数都是布尔值,无可厚非,同时为true才为true.与其他强类型语言不同的是,javascript逻辑与前后的操作数可以应用于任何类型. 而且 ...

随机推荐

  1. Git-根据tag创建分支

    有时候需要根据tag创建分支. 现在主分支上有一个tag为vtest.1.0.FINAL,主分支的名字为master. 1.执行:git origin fetch 获得最新. 2.通过:git bra ...

  2. Spring Cloud断路器Hystrix

    在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就会因依赖关系形成故障蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构就更加的不稳定.为了解决这样的问题,因此产生了断路器模式. 什么是 ...

  3. web安全之XSS注入

    之前在做项目的时候有遇到一些安全问题,XSS注入就是其中之一 那么,什么是XSS注入呢? XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.它指的是恶意攻击者往Web页面里插入 ...

  4. C#连接Access2013

    今天测试连接Access2013数据库,遇到错误,综合几个大神建议,解决了 我的系统是windows 2008 64位的,连接字符串如下: <connectionStrings> < ...

  5. JSONP是什么

    摘自:https://segmentfault.com/a/1190000007935557 一.JSONP的诞生 首先,因为ajax无法跨域,然后开发者就有所思考 其次,开发者发现, <scr ...

  6. 让机器说话(文字转美女语音,擅长中英文哦),大小600K(免费下载)!

    机器人之路的第二小步:说话(文字转语音美女哦),大小600K(免费下载)! 机器人之路的第二小步:说话(文字转语音美女哦),准确率特别高,普通话标准,中英文都可以说,大家可以体验一下,请下载到电脑上在 ...

  7. Docker 镜像安装 GitLab 中文社区版

    docker run \ --detach \ --publish : \ --publish : \ --name gitlab \ --restart unless-stopped \ --vol ...

  8. Linux 部署 ASP.NET Core 的一些问题记录

    异常错误: 关闭 IP6 #修改 vi /etc/sysctl.conf # 添加如下三条设置    net.ipv6.conf.all.disable_ipv6 = 1    net.ipv6.co ...

  9. Spring Cloud Eureka

    搭建服务注册中心 创建eureka-center,pom.xml如下: <?xml version="1.0" encoding="UTF-8"?> ...

  10. MySql中插入乱码问题解决

    今天在使用Java写入数据库时候,发现Insert语句和Update语句在执行过后,数据库中中文显示的是“??”,经过一番查阅,其中关键的问题在于编码格式是否统一. 其中创建表时候,每个关键字的格式都 ...