zoukankan      html  css  js  c++  java
  • JavaScript学习笔记-函数

    函数的两种创建方式:函数定义表达式、函数声明语句
    编译时,函数声明语句创建的函数会‘被提前’至外部函数的作用域顶部,在该作用域内可以被随意调用;
    而函数表达式创建的函数,要调用它必须赋值给一个变量,编译时将把它当做变量处理,会‘声明提前’,无法调用函数体本身;
    函数定义表达式创建的函数也可包含名称,主要用于递归调用;
    如果一个函数没有返回值,则返回值为undefined;
     
    函数调用:作为函数调用、作为对象的方法调用、作为构造函数、作为别的对象的方法间接调用(call()、apply()、bind())
    作为对象的方法调用时,函数的当前上下文是对象,即this的指向,可以通过返回对象本身(this)来实现“链式调用”
    这种方式创建函数要少用:var f = new Function('x','y','return x+y'),Function的构造函数创建的函数是动态运行和编译的,影响性能,它无法捕捉局部作用域;
    当有可选参数时,需把它放到参数列表最后,若传入的实参个数少于形参个数,则剩下的形参将赋值为undefined,所以最好在函数体内为省略的形参设定初始值,如a = a || 0;
    嵌套函数的this指向的是全局对象、undefined或调用它时的当前上下文,而非外层函数;
     
    定义函数时,若参数个数多且必须有序,则应把它先放入对象内,再把该对象作为参数传入,然后再处理函数的元素,这样就省了记参数顺序的麻烦;
     
    面向对象的模块化编程:见实例;
    为了防止全局变量与其它域的全局变量起冲突,需要将整个代码放入一个函数(或匿名函数)内,并立即执行,将其转化为局部变量,如:
    匿名函数模块:( function(){....}() ); 外部括号的作用是让编译器理解为是一个函数表达式;
    函数式模块:function myModule(){....}    myModule(); 先定义、后执行;
    全局变量模块:var module = ( function(){...} ) (); 该变量保存了一个立即执行的函数表达式创建的函数的返回值;
     
    闭包:
    (由于在函数外部不能直接的访问、修改函数的局部变量,所以需要使用闭包)
            在函数的外部,通过内部函数访问、修改外部函数的局部变量,这个内部函数就称为闭包,而这些局部变量就被内部函数一直引用着,即使外部函数退出后,它们也保持在内存中;
            在函数调用时都会自动包含一个this和一个arguments
    this指向的是当前上下文对象,闭包执行时的上下文对象通常不是外部函数,所以若要在闭包内使用this,需要在外部函数中将this保存在一个变量中var self = this,然后再使用变量self来绑定到外部函数;
    arguments绑定的是当前上下文函数的参数,他是类数组对象,若要让闭包使用外部函数的arguments,需先将外部的arguments绑定到一个变量,再通过该变量来访问,var outerArguments = arguments;
     
    循环中的闭包
    一个常见的错误出现在循环中使用闭包,假设我们需要在每次循环中调用循环序号
    for(var i =0; i <10; i++){
        setTimeout(function(){
            console.log(i);  
        },1000);
    }
    上面的代码不会输出数字 0 到 9,而是会输出数字 10 十次。
    当 console.log 被调用的时候,匿名函数保持对外部变量 i 的引用,此时 for循环已经结束, i 的值被修改成了 10.
    为了得到想要的结果,需要在每次循环中创建变量 i 的拷贝。
    避免引用错误
    为了正确的获得循环序号,最好使用 匿名包裹器(译者注:其实就是我们通常说的自执行匿名函数)。
    for(var i =0; i <10; i++){
        (function(e){
            setTimeout(function(){
                console.log(e);  
            },1000);
        })(i);
    }
    外部的匿名函数会立即执行,并把 i 作为它的参数,此时函数内 e 变量就拥有了 i 的一个拷贝。
     
    当传递给 setTimeout 的匿名函数执行时,它就拥有了对 e 的引用,而这个值是不会被循环改变的。
     
    有另一个方法完成同样的工作;那就是从匿名包装器中返回一个函数。这和上面的代码效果一样。
     
    for(var i =0; i <10; i++){
        setTimeout((function(e){
            returnfunction(){
                console.log(e);
            }
        })(i),1000)
    }
     
    函数式编程:见实例
  • 相关阅读:
    bzoj3262 陌上花开
    bzoj2738 矩阵乘法
    bzoj3110 [Zjoi2013]K大数查询
    bzoj2527 [Poi2011]Meteors
    bzoj1758 [Wc2010]重建计划
    启动应用程序的Activty多种方式
    隐藏应用图标的多种方式
    Loading Large Bitmaps Efficiently
    java中的匿名内部类总结
    android listview addHeaderView和addFooterView的注意事项
  • 原文地址:https://www.cnblogs.com/susufufu/p/5705809.html
Copyright © 2011-2022 走看看