JS中的函数定义及调用

1. JS中的函数就是对象

        当你发现函数有的时候难以理解时,把它看作一个对象就很好理解了,所以函数可以添加属性和方法。比如函数做参数,函数做返回值。

判断对象是否有该属性:attr in obj

var person = {
    age:20;
};
console.log('name' in person);  //false
console.log('age' in person);  //true

遍历对象属性:

for(var p in cat){
    console.log(p);
}

2. JS中的函数定义的三种方法

//function声明,因为它是声明,不用加分号
function add(){

}

//var赋值表达式,因为是赋值,所以要加分号
var add=function(){

};

//构造函数
var add=new Function('num1','num2','return num1+num2;');

三种函数定义方式的区别:

这涉及到预解析的机制。预解析就是:在当前的作用域中,JavaScript代码执行之前,浏览器首先会默认的把所有带var和function声明的变量进行提前的声明或者定义。

为什么是声明或者定义呢?因为var声明的变量和function声明的函数在预解析的时候有区别:var声明的变量在预解析的时候只是提前的声明,并未定义(这就是为什么我们访问没有声明的变量是undefined而不报错的原因);function声明的函数在预解析时会提前声明并且同时定义(所以我们在后面定义的函数,在前面也可以访问)。

由于三种定义函数方式的不同,function声明定义的函数预解析会提前,所以在函数前面访问也能访问到;var赋值表达式定义的函数相当于一个对象赋值给add,这样预解析时add提前声明(add=undefined),此时在它前面访问add没问题,等于undefined,但是调用add()这个函数就会报错,因为预解析时var add=undefined,并没有定义function,只是声明了。

但是,JS中并没有块级作用域的概念(if和for),代码块中的预解析会存在问题,所以尽量不要在for和if代码块中定义变量和函数。

3. JS中函数调用问题

(1)匿名函数自执行

function(){

}();//报错
//JS解析器会将function认为是声明,所以直接调用会出错,解决办法是不让function打头

(function(){
    
})();
//这样就避免了function打头

(function(){

}());
//这样也避免了function打头

!+-~function(){

}();
//这样也避免了function打头

(2)递归调用

function factorial(num){
    if(num<=1) return 1;
    return num*factorial(num-1);
}
console.log(factorial(5));

(3)构造函数的调用

var obj=new Person();//构造函数的调用
var ab=person();//普通函数的调用

//Object
new Object();
//Array
new Array();

//构造函数的调用必须new,否则就认为是普通函数的调用,返回值为object对象

(4)函数的间接调用

call和apply是Function的原型对象,它们能够将该函数当作一个方法绑定到指定对象上,并进行调用。也就是说,任何函数可以作为任何对象的方法来调用,哪怕这个函数不是那个对象的方法。

function.call(thisobj,args...)
function.apply(thisobj, [args])

function表示要调用的函数,thisobj表示要将function绑定的指定函数。call和apply方法的区别在于传参的形式不同,call方法可以接受多个参数列表,而apply方法接受一个数组。

var name='xm';
var person={};
person.name='xh';
person.getName=function () {
    return this.name;
};
console.log(person.getName());//xh
console.log(person.getName.call(window));//将person的getName方法绑定在window对象上,输出xm
console.log(person.getName.apply(window));//将person的getName方法绑定在window对象上,输出xm

(5)JS函数中的参数

实参>形参的情况:当不确定传入实参数目时,我们可以不写形参,通过arguments类数组(这里叫类数组,是因为它并没有数组的一些方法)获取形参的值和个数,然后进行相应的计算。如进行加法时:

    function add() {
        if(arguments.length===0) return;
        var sum=0;
        for(var i=0;i<arguments.length;i++){
            sum+=arguments[i];
        }
        return sum;
    }
    console.log(add());//undefined
    console.log(add(1));//1
    console.log(add(1,2));//3
    console.log(add(1,2,3));//6

arguments:类数组,每个函数都有一个arguments,arguments.callee指代函数的本体,它的使用方法如下:

function jiecheng(num){
    if(num<1) return 1;
    return num*arguments.callee(num-1);//即使函数名修改,内部也不用修改
}

但是,在严格模式( "use strict"; )下,不允许使用arguments.callee,解决方案如下:

var jiecheng=function fn(){
      if(num<1) return 1;
    return num*fn(num-1);//这样更改了函数名jiecheng,内部也不用改变
}

(6)JS中抛出错误

function add(num1,num2) {
    if(arguments.length!=add.length) throw new Error("请传入正确的参数");
    return num1+num2;
}
add(1);//错误
add(1,2);//因为上面出错,所以不会执行

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值