JS函数深入

函数的本质是对象

三种定义方式

1、  字面量=function声明

            function add() {
                // body...
            }
            add();

2、  var赋值表达式

            var add =  (argument) {
                            };
            add();
             fn(argument) {
                                fn();
                add();
            };
            add();
            fn();会报错,只能在函数体内调用

3、  构造函数

    new Function('num1','num2','return num1 + num2;');
            add();

三种定义方式区别:

字面量=function声明:预加载时add=function

    console.log(add());
     add() {
        return 1;
}

var赋值表达式:预加载时add=undefined

 () {
        ;
};

构造函数:少用

 

 

杂七杂八的知识点:

JS中没有块级作用域,所以不会在if中发生预解析,在外部预解析的时候,if中声明的所有函数都会被提前,所以无法达到按需定义的目的。

内部函数可以访问外部函数的变量(作用域链的机制)

 

 

案例:写出一个加法(add)函数,并在其内部定义一个函数(isNumber),用来判断add的参数是否可以转化为数字类型进行相加,

如果可以,就在页面中输出结果;

如果不能就退出add,给出提示“请传入数字类型的参数”

 add(num1,num2){
    if(isNaN(num1) || isNaN(num2)){
        alert('请传入数字类型的参数');
        return;
    }else{
        return parseInt(num1)+parseInt(num2);
    }
}

var num1=prompt('请输入数字1');

var num2=prompt('请输入数字2');

alert(add(num1,num2));

案例:匿名函数也是函数,当它自执行的时候会创建函数作用域,它里面的变量和函数都是局部的,当匿名函数执行完毕后会被销毁。所以我们在外面访问不到add

    return num1+num2;
        }
    }();
    document.write(add(1,2));报错

匿名函数自执行方式:

     () {
        console.log(1);
    }();

    ();
    })();

    !+-~);
    }();

递归调用:递归调用就是自己调用自己,但切记一定要有终止条件,否则函数将无限递归下去

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

方法的调用:

    document.onclick =  () {
        console.log('你点击了文档!');
    };
    document.onclick();
    var operation = {
        add:  (num1,num2) {
            return num1 + num2;
        },subtract: return num1 - () {
            console.log('@');
        },key:  () {
                    }
    };
    console.log(operation.add(1,2));
    console.log(operation['@'](1,2)); @符比较特别
    var key = 'add';
    console.log(operation[key](1,2));

链式调用

     num2);
            return this;
        },num2) {
            console.log(num1 -        }
    };
    operation.add(1,2).subtract(2,1);

间接调用:

对象没有call和apply方法,只有函数有

call和apply的唯一区别就在它们传参的方式上

apply可以将数组和类数组一次性的传递进函数中,call只能一个一个的传;

    var name = 'xm';
    var person = {};
    person.name = 'xh';
    person.getName = .name;
    };
    console.log(person.getName()); this指向person
    console.log(person.getName.call(window)); this指向window
    console.log(person.getName.apply(window)); this指向window

     num2;
    }
    console.log(add(1,1)">));
    var datas = [1,1)">];
    console.log(add.call(window,1,1)">));
    console.log(add.apply(window,datas)); apply(ele,[])

输出:'xm',[object Object]

person()就是普通函数的调用,返回值是return后面的内容:'xm' ; new person()是将person作为构造函数调用,返回的永远是对象 ; document.write没法输出对象,它会尝试着将其转换成字符串输出

 

输出:undefined

call可以改变函数中this的指向,这里在调用方法的时候将其this改为了window,所以this.value就变成了window.value,而window.value没有定义过,所以为undefined

 

 

函数的参数:

 add() {
    if (arguments.length == 0) var sum = 0for (var i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
     sum;
}
console.log(add());
console.log(add(1,2,3,4,5));

arguments

类数组,实质是类

 fn(name) {
    arguments[0] = '';
    console.log(name);
}
fn('xm');没有输出

arguments.callee 指代函数本身,多用于递归

计算阶乘方法一:

 factorial(num) {
    );
}
console.log(factorial(5));

计算阶乘方法二:

return num * arguments.callee(num - 1);
}
console.log(jiecheng(5));

计算阶乘方法三:

var jicheng =  fn(num) {
    return num * fn(num - 1);
};
console.log(jicheng(5));

判断传入实参的个数是否与形参相等

arguments.length实参个数

add.length形参个数

 

if (arguments.length != add.length) throw new Error('请传入' + add.length + '个参数!');
     num2;
}
console.log(add(1,1));
console.log(add(1));
console.log(add(1,3));

案例:

输出:1,1,3

1、 count()()这样调用,每次都会创建一个新的局部作用域,num的值会不断地被初始化为1

2、 return num++表示先返回num的值,再将num加1

3、 先将count()赋给fn,此时count()只调用了一次,接下来多次调用fn()的时候,count函数并没有多次调用,num只会在count函数调用的时候被初始化,所以多次调用fn()的时候num不会被多次初始化;由于fn相当于count函数的内层函数(var fn=count();这行代码执行后,就调用了count(),调用count后就将里面的函数赋值给了fn,所以说fn就相当于函数的内层函数了。),可以访问count中的变量num,所以多次调用fn函数,会将num的值累加;

相关文章

kindeditor4.x代码高亮功能默认使用的是prettify插件,prett...
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代...
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小