函数
说明
函数也是一个对象,只不过函数中可以封装某些功能。
创建函数
// 方式一
// 此方式基本不用
var fun = new Function("console.log('hello')");
console.log(typeof fun); // function
// 方式二
// 使用函数声明的方式
function myFunction() {
console.log('hello');
}
// 方式三
// 使用函数表达式(匿名函数)
var funExp = function() {
console.log('hello');
};
执行函数
// 方式一
fun();
// 方式二
myFunction();
// 方式三
funExp();
函数参数
函数中的参数默认值是 undefined
。
function a(e) {
console.log(e); // undefined
}
函数作为参数
function myAdd() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
console.log(sum);
return sum;
}
function fun1(a) {
a(1,2,3);
}
fun1(myAdd); // 传递函数对象,调用 myAdd 函数
// 做如下修改
function fun1(a) {
console.log(a); // myAdd(1,2);
}
fun1(myAdd(1,2));// 相当于使用 myAdd 的返回值。
函数作为返回值
function myAdd() {
function a() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
}
// 注意返回值带括号和不带括号的区别
// 不带括号表示返回该函数(对象)
// 带括号表示调用该函数,返回被调用函数的返回值(函数的返回值默认是 undefined)
return a;
}
var c = a;
c();
立即执行函数
立即执行函数也被称为 IIFE,函数被定义后立即执行,但是只会执行一次。而且函数会隐藏其实现过程,也不会污染全局的命名空间。
// 无参
(function() {
console.log("立即执行");
})();
// 有参
(function(x, y) {
console.log(x+y);
})(1, 2);
(function() {
var a = 1;
function test() {
consloe.log(++a);
}
window.$ = function() { // 向外暴露函数
return {
test: test
};
}
})()
$().test()
说明
JavaScript 中的函数,不会检查函数参数的类型和参数的个数。函数的默认返回值是 undefined
。
回调函数
回调函数不由用户调用,它是由系统调用,如 DOM 事件的回调函数、定时器的回调函数。
函数的方法
函数也是对象,所以,函数也有方法。
call
当函数调用该方法时,函数会被调用并执行。该方法可以将对象指定为函数的第一个参数,此时 this
就是传入的对象(即参数是谁,this
就是谁)。
function fun() {
console.log(this);
}
fun(); // window
fun.call(); // window
var obj = [];
fun.call(obj); // []
此外,可以将对象在实参之后依次排列。
var obj1 = {
name:'obj1',
method:function() {
console.log(this.name);
}
}
function f(a,b) {
console.log("a=" + a);
console.log("b=" + b);
}
f.call(obj1); // a 和 b 都是 undefined
f.call(obj1,1,2); // a = 1,b = 2
apply
当函数调用该方法时,函数会被调用并执行。该方法可以将对象指定为函数的第一个参数,此时 this
就是传入的对象(同 call
)。
var obj1 = {
name:'obj1',
method:function() {
console.log(this.name);
}
}
var obj2 = {
name:'obj2',
method:function() {
console.log(this.name);
}
}
obj1.method.call(obj2); // obj2
apply 的特性和 call 的特性稍有不同,在传递参数时,apply 需要把多余的参数封装到一个数组中。
var obj1 = {
name:'obj1',
method:function() {
console.log(this.name);
}
}
function f(a,b) {
console.log("a="+a);
console.log("b="+b);
}
f.apply(obj1);
f.apply(obj1,[1,2]);
说明
这两个方法实际上可以理解为,如果某个对象没有该方法,那么,可以通过 call 或 apply 让该对象临时拥有该方法,并且调用该方法。
arguments
浏览器传入函数的隐藏参数,它是一个类数组对象。函数的所有形参都会被封装到该对象中。
function f() {
console.log(arguments instanceof Array); // false
console.log(Array.isArray(arguments)); // false
}
callee 属性
arguments
通过调用该属性可以打印当前函数对象。
function f() {
console.log(arguments.callee == f); // true
}