JS函数与闭包问题

函数

1、定义

1.1函数声明
function test(){ 
}
function test(){
    document.write('a');
    document.write('b');
    document.write('c');}
1.2函数表达式
       1.2.1.命名函数表达式
        var test = function abc(){
            document.write('a');
        }
       1.2.2.匿名函数表达式------函数表达式
        test();
        var demo = function(){
            document.write();
        }
1.3函数通常为:高内聚,弱偶合

2、组成形式

2.1函数名称
如果有多个单词,第一个单词首字母小写,其他首字母大写,即小驼峰式
2.2参数
2.2.1形式参数,a,b
function sum(a, b){//默认定义a,b
    if(a > 10){document.write(a - b);
    }else if(a < 10){
    document.write(a + b);
    }else{
        document.write(10)
    }
}
2.2.2实际参数
sum(11, 2)
// 求形参长度
function sum(a){
    for(var i = 0; i < arguments.length; i++){
        console.log(arguments[i])
    }
}
2.2.3求实参长度
function sum(a, b, c, d){
    if(sum.length > arguments.length){
        console.log('形参多了');
    }else if(sum.length < arguments.length){
        console.log('实参多了');
    }else{
        console.log('相等')
    }
}
sum(11, 2, 3)
2.2.4不定参求和
function sum(){
    //arguments[0,1,2,3,4,5,6]
    var result = 0;
    for(var i = 0;i < arguments.length;i++){
        result += arguments[i];
    }
    console.log(result);
}
sum(1,2,3,4,5,6,7,8,9,10);
2.3返回值

return两点功能(同时生效)

2.3.1.终止
function sum(a, b){
    console.log('a');
    return;
    console.log('b');
}
2.3.2.返回值
function myNumber(target){
    return +target;
}
var num  = myNumber('123');
console.log(typeof(num) + " " + num);

3、预编译

3.1函数里面定义的变量为局域变量
3.2 js运行三部曲
语法分析
    执行之前先进性语法分析。
预编译
解释执行
3.3预编译
3.3.1
    1、imply golbal暗示全局变量 :
    即任何变量,如果变量未经声明就赋值,
    此变量就为全局对象所有。
        eg:a = 123;
        eg:var a = b = 123;
    2、一切声明的全局变量,全是window属性。
    eg:var a = 123;===> window.a = 123;
function test(){
      var a = b =123;
}
a为局部变量,b为全局变量
    函数声明整体提升
    变量 声明提升
3.3.2预编译四部曲
        1、创建AO(Activation Object)对象(局部变量)
        2、找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
        3、将实参值和形参统一
        4、在函数体里面找函数声明,值赋予函数体
        
        生成一个GO(Global Object)对象(全局变量)
        GO{ }

例子:

            console.log(test);
            function test(test) {
                console.log(test);
                var test = 234;
                console.log(test);
                function test( ){
                }
            }
            test(1);
            var test = 123;

4、作用域

4.1作用域精解
1[[scope]]:每一个JavaScript函数都有一个对象,对象中有些属性是我们可以访问,
但有些是不可以,这些属性仅供JavaScript引擎存取,[[scope]]就是其中的一个。
2[[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。
3作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合成链式链接,
我们把这种链式连接叫做作用域链
4执行期上下文:(就是AO,GO,就是即时的作用空间,用完就不用了,
就是把作用域链干掉了)当一个函数执行时,会创建一个称为执行期上下文的内部对象。
一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行器上下文都是独一无二的,所以多次调用函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行期上下文被销毁。
5查找变量:(在哪个函数里面中查找就从那个函数里面)从作用域的顶端依次向下查找。

5、闭包

5.1闭包的产生
    当内部函数被保存到外部时,将会生成闭包。
    闭包会导致原有作用域链不释放,造成内部泄露。(就是内存占用过多,内存余量不足)
5.2闭包的作用
5.2.1实现公有变量
        eg:函数累加器.
    function add(){
                var count = 0;
                function demo(){
                    count ++;
                    console.log(count); 
                }
                return demo;
            }
            counter();
5.2.2可以做缓存(存储结构)
        eg:eater
function eater(){
    var food =""
    var obj ={
       eat : function (){
           console.log("i am eating " + food);
           food = myFood;
      }
   }
   return obj;
}
var eater1 =eater();
eater1.push('banana');
eater1.eat();
5.2.3可以实现封装,属性私有化
        eg:Person()
    模块化开发,防止污染全局变量

6、立即执行函数

6.1定义:

此类函数没有声明,在一次执行过后即释放。适合做初始化工作。
针对初始化功能的函数

var num = (function (a, b, c){
    var d = a + b + c * 2 - 2;
    return d;
}(1, 2, 3));
6.2立即执行函数
    针对初始化功能的函数
        var num = (function (a, b, c){
            var d = a + b + c * 2 - 2;
            return d;
        }(1, 2, 3));
        (function (){}());w3c建议第一种
        例如:
        (function test(){
            console.log('a');
        }());
        (function (){})();
        只有表达式才能被执行符号执行
        函数声明
        function test () {
            var a = 123;
        }
        test();
        函数表达式
        能被执行符号执行的表达式,函数名自动忽略
        var test = function () {
            console.log('a');
        }()
        下面这种不报错也不执行
        function test(a, b, c, d) {
            console.log(a + b + c + d);
        }(1, 2, 3, 4);
6.3闭包实现吃东西
function test() {
        var food = "apple";
        var obj = {
            eatFood : function (){
                if(food != "") {
                    console.log("I am eating " + food +"!");
                    food = "";
                }else{
                    console.log("There is nothing! empty!");
                }
            },
            pushFood : function(myFood) {
                food = myFood;
            }
        }
        return obj;
    }
    var person = test();
    person.eatFood();
    person.eatFood();
    person.pushFood('banana');
    person.eatFood();
6.4一般用立即执行函数来解决闭包问题
    function test() {
        var arr = [];
        for(var i = 0; i < 10; i ++){
            (function (j) {
                arr[j] = function () {
                    console.log(j);
                }
            }(i))
        }
        return arr;
    }
    var myArr = test();
    for(var j = 0; j < 10; j++) {
        myArr[j]();
    }
    function a() {
        function b() {
            var bbb = 234;
            document.write(aaa);
        }
        var aaa = 123;
        return b;
    }
6.5常见的闭包问题:

function test(){
var liCollection = document.getElementsByTagName(‘li’);
for(var i = 0; i< liCollection.length; i++){
liCollection[j].onclick = function (){
console.log(j);
}
}
}
test();
解决方法:
function test(){
var liCollection = document.getElementsByTagName(‘li’);
for(var i = 0; i< liCollection.length; i++){
(function(j){
liCollection[j].onclick = function (){
console.log(j);
}
}(i))
}
}
test();

7、例题

7.1写一个函数

功能是告知你所选定的小动物的叫声

function scream(animal){
    switch(animal){
        case "dog" :
            document.write('wang');
            return;
        case "cat" :
            document.write('miao');
            return;
        case "fish" :
            document.write('o~o~o~');
            return;
    }
}
7.2定义一组函数

输入数字,逆转并输出汉字形式。

function reverse(){
    var num = window.prompt('input');
    var str = "";
    for(var i = num.length - 1; i >= 0; i --){
        str += transfer(num[i]);
    }
    document.write(str);
}
function transfer(target) {
    switch(target) {
        case "1" :
            return "壹";
        case "2" :
            return "贰";
        case "3" :
            return "叁";
    }
}
7.3阶乘
function jc(n) {
    if(n == 1) {
        return 1;
    }
    return n * jc(n - 1);
}
7.4递归
function mul(n) {
    //n的阶乘
    if(n == 1 || n == 0){
        return 1;
    }
    return n * mul(n - 1);
}
7.5斐波那契数列
fb(n) == fb(n - 1) + (n - 2);
function fb(n) {
    if(n == 1 || n == 2) {
        return 1;
    }s
        return fb(n - 1) + fb(n - 2);
}
7.6写一个方法,求字符串的字节长度
7.6.1

function retByteslen(target) {
var count = 0;
for(var i = 0; i < target.length; i++) {
if(target.charCodeAt(i) <= 255){
count ++;
}else if(target[i].charCodeAt(i) > 255){
count +=2;
}
}
console.log(count);
}

7.6.2优化

function retByteslen(target) {
var count = target.length;
for(var i = 0; i < target.length; i++) {
if(target.charCodeAt(i) > 255){
count ++;
}
}
console.log(count);
}

7.6.3再优化

function retByteslen(target) {
var count,
len;
count = len = target.length

for(var i = 0; i < len; i++) {
    if(target.charCodeAt(i) > 255){
        count ++;
    }
}
console.log(count);

}

7.7“,”操作符

","操作符:返回,后面的内容
eg:
var f=(
function f() {
return “1”;
},
function g() {
return 2;
}
)();
console.log(typeof f);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值