一、变量提升与函数提升
1、 变量提升
//例1:
var v='Hello World';
alert(v);// Hello World
//例2:
var v='Hello World';
(function(){
alert(v); // Hello World
})()
//例3:
var v='Hello World';
(function(){
alert(v); // undefined
var v='I love you';
})()
例3涉及到变量提升,很简单,就是把变量提升提到函数的top的地方。我么需要说明的是,变量提升只是提升变量的声明,并不会把赋值也提升上来。例3实际上是如下:
var v='Hello World';
(function(){
var v;
alert(v);
v='I love you';
})()
1、 函数提升
函数提升是把整个函数都提到前面去。在我们写js code 的时候,我们有两种写法,一种是函数表达式(字面量声明函数),另外一种是函数声明方式(关键字声明函数)。我们需要重点注意的是,只有函数声明形式才能被提升。
function myTest(){
foo();
function foo(){ alert("我来自 foo"); }
}
myTest(); //我来自 foo
function myTest(){
foo();
var foo =function foo(){ alert("我来自 foo"); }
}
myTest(); //报错: foo is not a function
二、函数字面量
字面量作为一种通用的,跨平台的数据交换格式。表达式的右边就是字面量。
字面量(string literal )包括4种:字符串字面量(string literal)、数组字面量(array literal)和对象字面量(object literal),函数字面量(function literal)
1. 字符串字面量是指双引号引住的一系列字符,双引号中可以没有字符,可以只有一个字符,也可以有很多个字符。 在编程语言中,字面量是一种表示值的记法。
var test="hello world!";
"hello world!"就是字符串字面量,test是变量名。
2.数组字面量
var team=["tom","john","smith","kobe"];
["tom","john","smith","kobe"]是数组字面量
3.对象字面量
var person={name:"tom",age:"26",sex:"male"};
{name:"tom",age:"26",sex:"male"}为对象字面量
4.函数字面量
var fun=function test(){};
函数字面量和函数关键字声明的函数的区别
函数字面量由4部分组成。
第一部分,关键词 function
第二部分,函数名,但是可有可无。
第三部分,包含在括号内的参数,当然参数也是可有可无的,括号不能少。
第四部分,是一组包裹在大括号的语句块,也就是函数要执行的具体代码,当然不写代码也没问题,{}是必须要的。
乍一看,这个不就是函数的定义么,怎么说是函数字面量呢?
其实,之前我们就说了一个限定条件,函数表达式。所以说函数表达式才是这里所说的函数字面量。
function () {}//这个写法符合上面4条,但却不是表达式,运行会报语法错误。
只有当作表达式的时候才能正常执行。
例1:
(function () {});
var a = function () {};
var obj = {fn: function () {}};
例2:
console.log(add2(1,1)); //输出2
function add2(a,b){
return a+b;
}
console.log(add1(1,1)); //报错:add1 is not a function
var add1 = function(a,b){
return a+b;
}
用关键字函数语句创建的函数add2,函数名称和函数体均被提前,在声明它之前就使用它。
但是使用var表达式(字面量函数)定义函数add1,只有变量声明提前了,变量初始化代码仍然在原来的位置,没法提前执行。
var fn = function test() { console.log(test); };
console.log(fn);
fn();
console.log(test); // 报 test 未定义
console.log(test); };也是函数字面量,test 是这个函数的名字,但是在这里只对函数体内可见,外部是不可调用的。
三、创建函数的几种方式
在javascript定义一个函数一般有如下三种方式:
1、函数关键字(function)语句:
function fun(x){alert(x);}
2、函数字面量(Function Literals):
var fun = function(x){alert(x);}
3、Function()构造函数:
var fun = new Function('x','alert(x);')
上面三种方法定义了同一个方法函数fun,第1种就是最常用的方法,后两种都是把一个函数复制给变量fun,而这个函数是没有名字的,即匿名函数。
函数字面量和Function()构造函数的区别:虽然函数字面量是一个匿名函数,但语法允许为其指定任意一个函数名,当写递归函数时可以调用它自己,使用Function()构造函数则不行。
var f = function fact(x) {
if (x < = 1) return 1;
else return x*fact(x-1);
};
四、匿名函数的调用方式
方式1,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用再去调用执行
(function(x,y){alert(x+y);return x+y;})(3,4);
方式2,调用函数,得到返回值。强制运算符使函数调用执行
(function(x,y){alert(x+y);return x+y;}(3,4));
方式3,匿名函数执行放在中括号内
[function(){console.log(this)}(this)] // window
方式4
(1)使用-/+运算符
-function(x,y){alert(x+y);return x+y;}(3,4);
+function(x,y){alert(x+y);return x+y;}(3,4);
--function(x,y){alert(x+y);return x+y;}(3,4);
++function(x,y){alert(x+y);return x+y;}(3,4);
(2)使用~运算符
~function(x, y){alert(x+y);return x+y;}(3, 4);
(3)使用!运算符
!function(){console.log(this)}();} //window
方式5
(1)匿名函数前加void
void function(x){x=x-1;alert(x);}(9); //效率最高
(2)匿名函数前加typeof
typeof function(){console.log(this) }(this) // window
(3)匿名函数前加delete
delete function(){console.log(this) }(this) // window
(4)匿名函数前加new
new function(win){console.log(win) }(this) //传参,//window
new function(){console.log(this) } //不传参,这里的this就不是window了
错误的调用方式
function(x,y){alert(x+y);return x+y;}(3,4);
http://www.cnblogs.com/ClareZjy/p/6365891.html