廖雪峰JS学习总结-函数篇

最近在刷廖雪峰的JS教程,把里面的本身不太清楚的东西在刷一遍。
教程网址:www.liaoxuefeng.com/wiki/001434…javascript

函数的定义和调用:

  1. 若是没有return语句,函数执行完毕后也会返回结果,只是结果为undefined
  2. JavaScript容许传入任意参数,即便函数内部不须要这些参数,也不影响调用。
  3. JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起做用,而且永远指向当前函数的调用者传入的全部参数。arguments相似Array但它不是一个Array
  4. 利用arguments即便函数不定义任何参数,仍是能够拿到参数的值。
    function abs() {
     if (arguments.length === 0) {
         return 0;
     }
     var x = arguments[0];
     return x >= 0 ? x : -x;
    }
    abs(); // 0
    abs(10); // 10
    abs(-9); // 9复制代码
  5. ES6引入了新的rest参数,他能够得到额外的rest参数,rest参数只能写在最后,前面用...标识,从运行结果可知,传入的参数先绑定a、b,多余的参数以数组形式交给变量rest,因此,再也不须要arguments咱们就获取了所有参数。(若是传入的参数连正常定义的参数都没填满,也没关系,rest参数会接收一个空数组(注意不是undefined))
    function foo(a, b, ...rest) {
     console.log('a = ' + a);
     console.log('b = ' + b);
     console.log(rest);
    }
    foo(1, 2, 3, 4, 5);
    // 结果:
    // a = 1
    // b = 2
    // Array [ 3, 4, 5 ]
    foo(1);
    // 结果:
    // a = 1
    // b = undefined
    // Array []复制代码
  6. return语句必须在一行上,若是必须为多行返回,须要在retrun后紧跟 {,正确的多行写法以下:
    function foo() {
     return { // 这里不会自动加分号,由于{表示语句还没有结束
         name: 'foo'
     };
    }复制代码

变量做用域:

  1. 若是用var在函数体内声明变量,该变量做用域为整个函数;由于这个缘由,在不一样函数内部用var申明的同名变量互相独立,互不影响。
  2. 因为函数能够相互嵌套,内部函数能够访问外部函数定义的变量,可是若是内部和外部都定义了同名变量怎么办了?JS函数查找变量会从自身定义函数开始,也就是从’内’向’外’,顺着做用域链查找,若是内部函数已经定义了,则会’屏蔽’掉外部函数变量。
  3. JS函数的var定义有个特色,它会先扫描整个函数体的语句,把全部var申明的变量“提高”到函数顶部,因此定义变量时,咱们应该严格遵照在函数内部先声明的规则。
  4. JavaScript默认有一个全局对象window,全局做用域的变量实际上被绑定到window的一个属性上了。
  5. 为了防止形成命名冲突,比较好的方法是把本身的全部变量和函数,都绑定到一个全局变量中:
    // 惟一的全局变量MYAPP:
    var MYAPP = {};
    // 其余变量:
    MYAPP.name = 'myapp';
    MYAPP.version = 1.0;
    // 其余函数:
    MYAPP.foo = function () {
     return 'foo';
    };复制代码
  6. 在for循环是没法定义具备局部做用域的的变量的。在ES6中可使用let替代var能够申明一个块级做用域的变量。
  7. 对于常量的定义,之前都是使用所有大写来规定,如今ES6总可使用关键字const来定义常量,constlet都具备块级做用域,而且const定义之后没法修改。
  8. 补充说明一下letconst的特色,不存在变量提高、会形成暂时性死区、不容许重复定义。

方法:

在一个对象中绑定函数,称为这个对象的方法。这里要介绍一个很坑爹的概念,就是this的指向问题。java

那么对于不一样的调用,这个this的指向分别是什么了??
答:this的指向在函数定义的时候是肯定不了的,只有函数执行的时候才能肯定this到底指向谁,实际上this的最终指向的是那个调用它的对象。
在《javascript语言精髓》中大概归纳了4种调用方式:数组

1. 方法调用模式
2. 函数调用模式
3. 构造器调用模式
4. apply/call调用模式复制代码

特别补充:闭包

  1. 在构造器调用时,若是加入了return而且return了一个对象,this会指向这个return的对象。
  2. 严格模式下在函数内部定义的函数,this指向undefined(在非strict模式下,它指向全局对象window

那么有没有办法去控制this的指向了?
有的,可使用函数自己的apply方法,它接收两个参数,第一个参数就是须要绑定的this变量,第二个参数是Array,表示函数自己的参数。另外一个与apply()相似的方法是call(),惟一区别是:app

  • apply()把参数打包成Array再传入;
  • call()把参数按顺序传入。
    另外ES5还加入了一个bind()方法,它会建立一个函数的实例,其this值会被绑定到传给bind()函数的值。

利用apply(),咱们还能够动态改变函数的行为。
JavaScript的全部对象都是动态的,即便内置的函数,咱们也能够从新指向新的函数。函数

高阶函数:

  1. 一个函数接收另外一个函数做为参数,这种函数就称之为高阶函数。
  2. forEach方法,是最基本的方法,就是遍历与循环,默认有3个传参:分别是遍历的数组内容item、数组索引index、和当前遍历数组Array。另外,除去第一个必须的回调函数参数,还能够接受一个上下文参数(改变回调函数的this指向);而且forEach不会遍历空元素。
  3. map方法,基本用法与forEach一致,可是不一样的,它会返回一个新的数组,因此在callback须要有return值,若是没有,会返回undefined。(从字面理解,map就是映射的意思)
  4. filter方法,用法和map很类似,从字面理解,就是过滤、筛选的意思。可是函数的callback须要返回布尔值truefalse,而且返回值只须要为弱等==便可。
  5. some 方法,对数组中每一项运行指定函数,若是该函数对任一项返回true,则返回true。(一旦遇到true,就会中断循环,返回true,相似于||判断)
  6. every方法,对数组中的每一项运行给定函数,若是该函数对每一项返回true,则返回true。(一旦遇到false,就会中断循环,返回false,相似于&&判断)
  7. sort方法,默认把全部元素先转换为String再进行ASCII码排序,因此这个很坑爹。要想正确的排序,须要添加一个函数。sort方法,能够接受一个回调函数,默认有两个传参:分别是比较的数组项。

闭包(还要在研究一下,之后补充吧):

「闭包」,是指那些可以访问独立(自由)变量的函数(变量在本地使用,但定义在一个封闭的做用域中)。换句话说,这些函数能够“记忆”它被建立时候的环境。特性:ui

  1. 函数嵌套函数
  2. 函数内部能够引用外部的参数和变量
  3. 参数和变量不会被垃圾回收机制回收

箭头函数:

  1. 箭头函数使得表达更加简洁。
  2. 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
  3. 不能够看成构造函数,也就是说,不可使用new命令,不然会抛出一个错误。
  4. 不可使用arguments对象,该对象在函数体内不存在。若是要用,能够用Rest参数代替。
  5. 不可使用yield命令,所以箭头函数不能用做Generator函数。

Generator:

  1. Generator 函数是协程在 ES6 的实现,最大特色就是能够交出函数的执行权(即暂停执行)。
  2. next法返回值的value属性,是 Generator 函数向外输出数据;next方法还能够接受参数,向 Generator 函数体内输入数据。
  3. Generator 函数内部还能够部署错误处理代码,捕获函数体外抛出的错误。

有错误但愿指出,必定会及时修改!this

相关文章
相关标签/搜索