函数

函数 - 图1 :::info 在JS中,函数是对象,能和其他值类型一样,可以赋值给变量,也可以作为函数的返回值。
在C语言中,函数实体比其他的值实体低一级,函数作为子程序只能被调用,而不能有函数表达式或者函数赋值给变量。 :::

写函数:

  1. 考虑函数定义方式
  2. 输入、输出
  3. 观察周围的词法环境记录。注意动态环境记录项:this、arguments、new.target
  4. 写逻辑算法

函数定义

函数名、形参、函数体
函数 - 图2

箭头函数

lambda函数、匿名函数。
函数 - 图3 :::info 匿名函数就是函数没有名字,说明匿名函数不需要通过函数名复用,仅仅作为代码片段,能够快速插入代码片段,十分方便。 :::

IIFE

ES6已经被淘汰的语法,了解即可。IIFE主要是利用函数作用域,模拟块级、模块作用域。但是ES6提供内置语法实现块作用域、模块化。

  1. /**
  2. * IIFE中是匿名函数,函数名写不写是一样的。因为函数表达式执行完后,函数就被销毁,函数不需要复用。
  3. */
  4. (function () {
  5. for(var i = 0; i < 2; i++){
  6. console.log(i);
  7. }
  8. })();
  9. //IIFE 第二种写法,W3C推荐写法
  10. (function () {
  11. for(var i = 0; i < 2; i++){
  12. console.log(i);
  13. }
  14. }());
  15. //IIFE另一种语法
  16. + / - / ! / 0 || / 0 && function (){} (); //在函数前加上运算符也会将函数转化为IIFE
  17. //面试题中特殊的写法
  18. function add(a){ //这里不能使用匿名函数
  19. console.log(a)
  20. }(2); //因为这里传了值,JS引擎不会认为这是IIFE语法错误。JS引擎会判断为这是一个函数声明和一个没有实际含义的表达式(2);最终不会报错。
  21. //注意一种语法错误写法,函数执行符号()前面一定是表达式
  22. function add() {
  23. console.log(1);
  24. }(); //()前面不是表达式,而是函数声明,不能直接调用执行。(指针)函数名 +()+ ; 函数才能调用执行。

函数执行上下文

函数在执行时,除了周围嵌套的词法环境(作用域)以外,还会创建函数本身的词法环境,包含有几个的隐藏环境项(arguments、this、new.target),这些环境项在函数执行期间动态确定。

arguments

ES6之前arguments对象主要解决收集可变参数长度的问题,ES6有了…运算符,arguments对象就被淘汰,直接使用命名参数。箭头函数在ES6标准中已经取消支持arguments对象。

函数 - 图4

  1. //非严格模式,参数没有默认值,arguments和形参在更改值的时候会同步。
  2. function sum(a, b) {
  3. a = 12;
  4. console.log(arguments[0]); //12
  5. arguments[0] = 10;
  6. console.log(a); //10
  7. }
  8. sum(1, 2);
  9. //严格模式中arguments和命名形参不会同步
  10. function sum(a, b) {
  11. "use strict";
  12. a = 12;
  13. console.log(arguments[0]); //1
  14. arguments[0] = 10;
  15. console.log(a); //12
  16. }
  17. sum(1, 2);
  18. //形参使用默认值时arguments的行为自动切换为严格模式。
  19. function foo(a = 1) {
  20. a = 2;
  21. console.log(arguments[0]); //42
  22. }
  23. foo(42);

:::info 非严格模式,形参和实参arguments相互之间产生同步,语义不明确。(不要使用)
严格模式,形参和实参互不影响,语义也更加明确。(模块作用域、形参默认值都会使函数切换为严格模式) :::

this

在可执行代码执行时,绑定this的值。

函数中的this

普通函数内使用this没有意义。 :::info

  • 非严格模式,this指向的是window对象。
  • 严格模式,函数内没有设置this,this指向的是undefined。 :::

    方法中的this

    this指向的是调用该方法的上下文对象。 :::info this实际应用就是基于对象中的方法。这一点也可以说是函数和方法的本质区别,方法的执行上下文中隐含有this。 :::

    箭头函数中的this

    :::info 箭头函数没有this,会在函数定义时确定,找上一级作用域中的this。 ::: ```javascript var obj = { count : 10, doSomethingLater : function (){
    1. setTimeout(function(){ //异步函数中的函数参数,是在window对象中执行。
    2. this.count++;
    3. console.log(this.count);
    4. }, 300);
    } }

var obj = { count : 10, doSomethingLater : function(){
setTimeout( () => { //上一级作用域就是方法doSomethingLater中的this this.count++; console.log(this.count); }, 300); } }

var obj = { i: 10, b: () => console.log(this.i, this), //上一级作用域是window c: function() { console.log(this.i, this); } } ```

new.target

检测函数是否使用new关键字调用。

  • 是:指向构造函数
  • 不是:undefined