概念
函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块
js 支持两种函数:一类是语言内部的函数(如eval() ),另一类是自己创建的。
在 JavaScript 函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它。(该变量的作用域是局部的)。您可以在不同的函数中使用名称相同的局部变量,因为只有声明过该变量的函数才能识别出该变量。
函数调用
有如下四种调用js函数的方式:
1. 作为函数
2. 作为方法
3. 作为构造函数
4. 通过call()和apply()
返回函数的函数
- 当函数没有确定返回值时,undefined
- 当函数有返回值时,返回值是什么就返回什么。我们可以通过使用 return 语句实现将函数返回调用它的地方。在使用 return 语句时,函数会停止执行,并返回指定的值。函数通常会返回一个唯一值,那么这个值也可能是另一个函数:
- 3.
<script type="text/javascript">
//函数表达式
var box = function(){
var a=1;
return function(){
alert(a++)
}
alert(a);//永远不会执行
}
alert(box());//弹出"function(){alert(a++)}"
</script>
在这里,我们只需将返回值赋值给某个变量,然后就可以像使用一般函数那样调用它了
<script type="text/javascript">
var box = function(){
var a=1;
return function(){
alert(++a)
}
}
var newFunc = box();
newFunc();//2
</script>
如果想让返回的函数立即执行,亦可以使用box()()来执行这段代码。
ECMAScript所有函数的参数都是按值传递的,言下之意就是参数不会按引用传递。
PS:如果存在按引用传递的话,那么函数里的那个变量将会是全局变量,在外部也可以访问。
(1)值类型:数值、布尔值、null、undefined。
(2)引用类型:对象、数组、函数。
引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象;
创建匿名函数
function(){
return ‘hi’; //单独的匿名函数是无法运行的,就算能运行也无法调用,因为没有名字
}
这种匿名函数的用法在JQuery中非常多。直接声明一个匿名函数,立即使用。用匿名函数的好处就是省得定义一个用一次就不用的函数,而且免了命名冲突的问题,js中没有命名空间的概念,因此很容易函数名字冲突,一旦命名冲突以最后声明的为准。
在javascript语言里任何匿名函数都是属于window对象。在定义匿名函数时候它会返回自己的内存地址,如果此时有个变量接收了这个内存地址,那么匿名函数就能在程序里被使用了,因为匿名函数也是在全局执行环境构造时候定义和赋值,所以匿名函数的this指向也是window对象
(function(){
console.log(this === window);//true
})();
通过自我执行执行匿名函数
//通过自我执行来执行匿名函数
<script type="text/javascript">
(function (){ // (匿名函数)();第一圆括号放匿名函数,第二个圆括号执行
alert('Lee');
})();
</script>
吧匿名函数自我执行的返回值赋值给变量
<script type="text/javascript">
var box = (function (){
alert('Lee');
})(); //弹出”Lee”;
alert(box); //弹出 undefined,如果写出alert(box()),那么只会弹出一个"Lee"
</script>
var box= (function () {
return 'hi';
})();
console.log(box);//hi
自我执行匿名函数的传参:
//自我执行匿名函数的传参
<script type="text/javascript">
(function (age){
alert(age);
})(100); //弹出100
</script>
自执行函数的三种写法
var result = function (){
alert(2);
}();
var result = (function () {
console.log(2);
})();
var result = (function () {
return 2;
}());
js创建动态函数
js支持创建动态函数,动态函数必须用Function对象来定义(Function是js中的一个对象,是固定不变的,规定Function对象的”F”必须大写,当是function的时候,我们知道是定义函数的时候所使用的一个关键字:function funName(x,y),当是Function的时候(F大写的时候),我们知道是js中的对象)
创建动态函数的基本格式:var 变量名 = new Function(“参数1”,”参数2”,”参数n”,”执行语句”);
看下面的一段代码:
<script type="text/javascript">
var square = new Function ("x","y","var sum ; sum = x+y;return sum;");
alert("square(2,3)的结果是:"+square(2,3)); //square(2,3)的结果是:5
</script>
quare是动态创建的函数,在Function对象后面的括号里的每一部分内容都必须是字符串形式的,也就是说都必须用引号(””或者是”)括起来
这段代码:
var square = new Function ("x","y","var sum ; sum = x+y;return sum;");
和下面这段代码:
//函数声明
function square (x,y){
var sum;
sum = x+y;
return sum;
}
是一摸一样的,只不过一个是动态函数,一个是静态函数。
我们为什么要把代码分成一小段一小段的代码呢?,把一个字符串分成了若干个独立的字符串的优点就在于我们可以通过修改其中的某些字符串来随时改变函数的作用。
回调函数
回调就是一个函数的调用过程。那么就从理解这个调用过程开始吧。函数a有一个参数,这个参数是个函数b,当函数a执行完以后执行函数b。那么这个过程就叫回调。
其实中文也很好理解:回调,回调,就是回头调用的意思。函数a的事先干完,回头再调用函数b。
这里必须清楚一点:函数b是你以参数形式传给函数a的,那么函数b就叫回调函数。
在jquery里的绝大多数效果函数都涉及到callback函数。jquery效果函数
例如:
<script type="text/javascript">
$("div").show(1000,function(){
//callback function
});
</script>
Callback实际上是,当一个函数执行完后,现执行的那个函数就是所谓的callback函数。怎么样?很好理解吧……
方法和函数的区别
var arr = [1,2,3,4,5]
var a =12; // 变量:自由的
arr.a= 5; //属性:属于一个对象
function show() //函数:自由的
{
alert(‘a’);
}
arr.fn = function() //方法:属于一个对象
{
alert(‘b’
);
}
其实方法就是函数,只不过方法是有所属的对象。
我们所熟知的,将函数绑定到 click 事件
语法:
$(selector).click(function
参数 | 描述 |
---|---|
function | 可选。规定当发生 click 事件时运行的函数. |
这种形式在jquery中经常见到。它是将function当做该方法的参数,向该方法添加一个事件处理函数。
*js全局函数
全局函数与内置对象的属性或方法不是一个概念。全局函数它不属于任何一个内置对象。
JavaScript 中包含以下 7 个全局函数,用于完成一些常用的功能:
1. escape( )
2. eval( )
3. parseFloat( )
4. unescape( )
5. isFinite( )
6. isNaN( )
7. parseInt( )
函数的几个作用
- 作为一个类构造器使用
function Class(){}
Class.prototype={};
var item=new Class();
- 作为闭包使用
这里写代码片(function(){
//独立作用域
})();
- 作为构造函数调用
<script type="text/javascript">
function Test(){//大写,以区分普通函数
this.x = 10;
}
var obj = new Test();
alert(obj.x); //弹出 10;
</script>
可以使用 new 运算符结合像 Object()、Date() 和 Function() 这样的预定义的构造函数来创建对象并对其初始化。面向对象的编程其强有力的特征是定义自定义构造函数以创建脚本中使用的自定义对象的能力。创建了自定义的构造函数,这样就可以创建具有已定义属性的对象。下面是自定义函数的示例(注意 this 关键字的使用)。
function Circle (xPoint, yPoint, radius) {
this.x = xPoint; // 圆心的 x 坐标。
this.y = yPoint; // 圆心的 y 坐标。
this.r = radius; // 圆的半径。
}
调用 Circle 构造函数时,给出圆心点的值和圆的半径(所有这些元素是完全定义一个独特的圆对象所必需的)。结束时 Circle 对象包含三个属性。下面是如何例示 Circle 对象。
var aCircle = new Circle(5, 11, 99);
使用构造器函数的优点是,它可以根据参数来构造不同的对象。 缺点是构造时每个实例对象都会生成重复调用对象的方法,造成了内存的浪费。
<script type="text/javascript">
function Test(name){
this.occupation = "coder";
this.name = name;
this.whoAreYou = function(){
return "I'm " + this.name + "and I'm a " + this.occupation;
}
}
var obj = new Test('trigkit4');//利用同一个构造器创建不同的对象
var obj2 = new Test('student');
obj.whoAreYou();//"I'm trigkit4 and I'm a corder"
obj2.whoAreYou();//"I'm student and I'm a corder"
</script>
依照惯例,我们应该将构造器函数的首字母大写,以便显著地区别于一般的函数。
以下两种形式的定义函数方式是等价的。
<script type="text/javascript">
var test = function(){
alert("Hello World");
}
alert(typeof(test));//output function
</script>
这里明确定义了一个变量test,他的初始值被赋予了一个function实体
<script type="text/javascript">
function test(){
alert("Hello World");
}
alert(typeof(test));//output function
</script>
看看下面这种定义式函数形式:
<script type="text/javascript">
function test(){
alert("Hello World");
};
test();//居然输出Hello,很奇怪不是吗?
function test(){
alert("Hello");
};
test();//正常滴输出了Hello
</script>
很显然,第一个函数并没有起到作用,很奇怪不是吗?
我们知道,javascript解析引擎并不是一行一行地执行代码,而是一段一段地执行代码。在同一段程序的分析执行中,定义式的函数语句会被优先执行,所以第一个定义的代码逻辑已经被第二个覆盖了,所以两次调用相同函数,只会执行第二个。
作为值的函数
函数在js中不仅是一种语法,也是一个值。也就是说可以将函数赋值给变量,存储在对象的属性或数组的元素中,作为参数传入另一个函数中。
函数的名字实际是看不见的,它仅仅是变量的名字,这个变量指代函数对象
<script type="text/javascript">
function square(x,y){
return x*y;
}
var s = square; //s和square指代同一个函数
square(2,3);//6
s(2,4);//8
</script>
除了可以将函数赋值给变量,同样可以将函数赋值给对象的属性,当函数作为对象的属性调用时,函数就称为方法
prototype属性
每一个函数都包含prototype属性,这个属性指向一个对象的引用,这个对象称为原型对象
参数arguments
当函数被调用时,会得到一个免费奉送的参数数组,那就是arguments数组。通过它,函数可以访问所有它被调用时传递给他的参数列表。这使得编写一个无需指定参数个数的函数成为可能。
<script type="text/javascript">
var sum = function(){
var i ,sum =0;
for(i = 0;i<arguments.length;i+=1){
sum+=arguments[i];
}
return sum;
};
document.writeln(sum(4,5,23,13,35,46,-10));//116
</script>