关于函数声明,它的一个重要特征就是函数声明提升,意思是在执行代码之间会读取函数声明,意思是在执行代码之前会先读取函数声明。这就意味着可以把函数声明放在调用它的语句

后面。

sayHi();
function sayHi(){
alert("Hi!");
}

理解函数提升的关键,就是理解函数声明与函数表达式之间的区别。

//不要这样做
if(condition){
function sayHi(){
alert("HI!");
}
}else{
function sayHi(){
alert("Yo!");
}
}

表面上看,以上代码表示在condition为true时,使用一个sayHi()的定义;否则,就使用另一个定义。实际上,这在ECMSscript中属于无效语法,JavaScript引擎会尝试修正错误,
将其转换为合理状态。不过,如果是使用函数表达式,那就没什么问题了。

//可以这样做
var sayHi;
if(condition){
sayHi=function(){
alert("Hi!");
}
}
else{
function sayHi(){
alert("Yo!");
}
}

这个例子不会有什么意外,不同的函数会根据condition被赋值给sayHi.

递归

我们知道,argument.callee是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用,例如:

function factorial(num){
if(num<=1){
return 1;
}else{
return num*argument.callee(num-1);
}
}

闭包

闭包是指有权访问另一个函数作用域中的变更的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

function createComparisonFunction(propertyName){
return function(object1,object2){
var value1=object1[propertyName];
var value2=object2[propertyName];
if(value1<value2){
return -1;
} else if(value1>value2){
return 1;
}else{
return 0;
}
}
}

闭包与变更

作用域链的这种配置机制引出一个值得注意的副作用,即闭包只能取得包含函数中任何变更的最后一个值。如下面这个例子:

function createFunctions(){
var result=new Array();
for(var i=0;i<10;i++){
result[i]=function(){
return i;
}
}
return result;
}

这个函数会返回一个函数数组。表面上看,似乎每个函数都应该返回自己的索引值,即位置0的函数返回0,位置1的函数返回1,以此类推。但实际上,每个函数都返回10。因为每个
函数作用域链中都保存着createFunctions()函数的活动对象(只是保存着对匿名函数function(){return i;}的引用),所以它们返回的都是最后一个i.w但是,我们可以通过创建
另一个匿名函数强制让闭包的行为符合预期,如下所示:

function createFunctions(){
var result=new Array();
for(var i=0;i<10;i++){
result[i]= function(num){
return function(){
return num;
}
}(i)
}
return result;
}

关于this对象

我们知道,this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等 于那个对象。不过,匿名函数的
执行环境具有全局性,因此,其this对象通过指向window

var name="The Window";
var object={
name:"My Object",
getNameFunc:function(){
return function(){
return this.name;
}
}
}
alert(object.getNameFunc()()); //"The Window" ("在非严格模式下")

前面提到过,每个函数在被调用时都会自动取得两个特殊变更:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中
的这两个。不过,把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了。如下所示:

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

模仿块级作用域

如前所述,JavaScript没有块级作用域的概念。这意味磁卡在块语句中定义的变量,实际上是包含在函数中而非语句中创建的,来看下面的例子.

function outputNumbers(count){
for(var i=0;i<count;i++){
alert(i);
}
alert(i); //计数
}

即使像下面这样错误的重新声明同一个变量,也不会改变它的值。

function outputNumbers(count){
for(var i=0;i<count;i++){
alert(i);
}
var i; //重新声明变更
alert(i); //计数
}

JavaScript从来不会告诉你是否多次声明了同一个变量;遇到这种情况,它只会对后续的声明视而不见。匿名函数可以用来模仿块级作用域并避免这个问题。
用作块级作用域的匿名函数的语法如下所示:

(function(){
//这里是块级作用域
})();

以上代码定义并立即调用了一个匿名函数。将函数声明包含在一对圆括号中,表示它实际上是一个函数表达式。而紧随其后的另一对圆括号会立即调用这个函数。
无论在什么地方,只要临时需要一些变量,就可以使用私有作用域,例如:

function outputNumbers(count){
(function(){
for(var i=0;i<count;i++){
alert(i);
}
})();
alert(i); //导致一个错误!
}

JavaScript高级程序设计学习笔记--函数表达式的更多相关文章

  1. javascript高级程序设计读书笔记----函数表达式

    定义函数两种方式: 1.函数声明 function sayHi(){ alert("Hi"); } sayHi();//调用函数 2.函数表达式 var sayHi = funct ...

  2. JavaScript高级程序设计---学习笔记(一)

    今天,2017.3.17开始利用课余时间仔细学习<JavaScript高级程序设计>,将需要掌握的知识点记录下来,争取把书里的所有代码敲一遍并掌握. 1.标识符命名最好是第一个字母小写,剩 ...

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

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

  4. JavaScript高级程序设计学习笔记第五章--引用类型(函数部分)

    四.Function类型: 1.函数定义的方法: 函数声明:function sum (num1, num2) {return num1 + num2;} 函数表达式:var sum = functi ...

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

    <!--<script> // 异步请求封装 IE6即以上浏览器 // ajax(url,fnSucc,selectID,fnFaild) //url 请求地址 //fnSucc 异 ...

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

    函数表达式 定义函数的方式有两种:一种是函数声明,另一种是函数表达式. 关于函数声明,它的一个重要特征就是函数声明提升,意思是在执行代码之前会先读取函数声明所以可以把函数声明放在调用它的语句后面. 而 ...

  7. JavaScript高级程序设计学习笔记--引用类型

    Object类型 对象字面量表示法: var person={ name:"Nicholas", age:29, 5:true }; 这人例子会创建一个对象,包含三个属性:name ...

  8. JavaScript高级程序设计学习笔记第二十章--JSON

    1.JSON:JavaScript Object Notation, JavaScript 对象表示法. 2.最重要的是要理解它是一种数据格式,不是一种编程语言.虽然具有相同的语法形式,但 JSON ...

  9. JavaScript高级程序设计---学习笔记(二)

    面向对象程序设计1.属性类型.定义多属性.读取属性特性对象的属性在创建时都带有一些特征值,JavaScript通过这些特征值来定义它们的行为.这些特性是为了实现JavaScript引擎用的,因此不能直 ...

随机推荐

  1. [设计模式] javascript 之 桥接模式

    桥接模式说明 定义:分离抽象化与实现化,使之可以自由独立的变化: 说明:由于软件环境需求原因,使得类型抽象具有多种实现以自身变化定义等情况,这使得我们要分离抽象实现与具体实现,使得抽象化与实现化解耦, ...

  2. WCF服务显示的是服务器名称而不是IP地址...

    打开http://xx.xx.xx.xx:端口号/Service1.svc页面显示的服务地址为: http://xx_yy_server:端口号/Service1.svc?wsdl 是显示的服务器的名 ...

  3. POJ 1905 Expanding Rods

                           Expanding Rods Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1 ...

  4. 用MVC的辅助方法自定义了两个控件:“可编辑的下拉框控件”和“文本框日历控件”

    接触MVC也没多长时间,一开始学的时候绝得MVC结构比较清晰.后来入了门具体操作下来感觉MVC控件怎么这么少还不可以像ASP.net form那样拖拽.这样设计界面来,想我种以前没学过JS,Jquer ...

  5. 【C语言入门教程】7.5 枚举

    在实际应用中,有的变量只有几种可能取值.如人的性别只有两种可能取值,星期只有七种可能取值.在 C 语言中对这样取值比较特殊的变量可以定义为枚举类型.所谓枚举是指将变量的值一一列举出来,变量只限于列举出 ...

  6. ajax提交Form

    Jquery的$.ajax方法可以实现ajax调用,要设置url,post,参数等. 如果要提交现有Form需要写很多代码,何不直接将Form的提交直接转移到ajax中呢. 以前的处理方法 如Form ...

  7. java自定义标签 权限

    <?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java ...

  8. HDU 5033 Building

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5033 解题报告:在一条x轴上有n个建筑物,每个建筑物有一个高度h,然后现在有q次查询,查询的内容是假设 ...

  9. mac 下载安装 IntelliJ IDEA Tomcat

    (1)Download IntelliJ IDEA https://www.jetbrains.com/idea/download/ (2)找了个激活码 http://www.oschina.net/ ...

  10. 关于jquery自带动画效果的stop()问题

    首先先来看一下jquery中stop()的用法 stop()用于在动画执行前停止正在执行的动画 stop(stopAll,goToEnd)的两个参数为布尔值: stopAll:true/false:是 ...