函数Function

  • 函数定义
    function abc(x){}
    var abc = function(){}
  • JS中允许传入任意个参数而不影响调用,但只会用到定义数量的参数.为避免传入空值,可以对传入值进行检查.
    function abc(x){
      if(typeof x != 'number'){
          throw 'Not a number';
      }//先对传入参数x做一个判断
    }
  • arguments
    只在函数内部起作用,永远指向函数的调用者传入的所有参数,类似于Array订单不是Array.
    function abc(){
      if(arguments.length === 0){
          return 0;
      }
      var x = arguments[0];
      return x >= 0 ? x : -x;
    }//可以获得调用者所有的参数,即使汉书没有定义参数
    abc();//返回0
  • arguments常用于判断传入参数的个数
    //foo[a[,b],c]
    //接受2-3个参数,b是可选参数,如果只传入2个参数b默认为Null
    function foo(a,b,c){
      if(arguments.length === 2){//实际拿到的参数是a和b,c为undefined
          c = b;//b赋值给c
          b = null;
      }
    }
  • 可选参数的传入待我再做研究
  • Rest参数
    ES6中新引入了rest参数,用于获取指定参数以外的剩余参数
    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[]
  • 用rest参数编写一个sum()函数,接受任意个参数并且返回他们的和
    'use strict';
    function sum(...rest) {
      let sum = 0;
      for(let i = 0; i < rest.length; i++){
          sum += rest[i];
      }
      return(sum);
    }

变量作用域与解构赋值

  • 1.在函数体中声明变量,只在函数中起作用,作用域为整个函数体,在函数体外不可引用该变量.不同函数体之间的同名变量相互独立,互不影响

  • 2.嵌套函数中的内部变量可以访问外部变量,反之则不行.如果内外定义了重名的变量,则内部的函数变量将会"屏蔽"外部函数变量

  • 3.变量提升:JS函数会扫描整个函数体的语句,将所有的申明变量提升到函数顶部

    function foo() {
      var y; // 提升变量y的申明,此时y为undefined
      var x = 'Hello, ' + y;
      console.log(x);
      y = 'Bob';
    }
    foo();//Hello,undefined

    不报错是因为y变量在之后声明了,JS自动提升了变量y的声明,但不会提升变量y的值.

  • 所以必须在开头定义所有变量

  • 4.全局作用域:全局对象window对象,有且只有一个全局作用域的变量实际上被绑定到window的一个属性course上.在函数定义中,以var abc = function(){}定义的函数实际上也是一个全局变量,因此顶层函数的定义也被视为一个全局变量并绑定到window对象中.这说明在JS中实际上只有一个全局作用域,任何变量(包括函数),如果没有在当前的函数作用域中找到,就会继续网上查找,如果最后在全局作用域中也没有找到,则报ReferenceError错误

  • 5.名字空间:全局变量会绑定到window当中,如果不同JS文件中使用了相同的全局变量,或定义了相同的顶层函数则会造成冲突.

  • 减少冲突:把自己所有的变量全部绑定到一个全局变量中

    // 唯一的全局变量MYAPP:
    var MYAPP = {};
    // 其他变量:
    MYAPP.name = 'myapp';
    MYAPP.version = 1.0;
    // 其他函数:
    MYAPP.foo = function () {
       return 'foo';
    };

    把自己的代码全部放入唯一的名字空间中,会大大减少全局变量冲突的可能

  • 6.局部作用域
    JS中变量的作用域实际上是函数内部,但无法定义具有局部作用域的变量,因此在ES6中引入let替代var,可以在申明一个块级作用域的变量,同时引入const来定义常量,也可以定义.
    简而言之:var定义的变量在整一个函数中都有用,let定义的作用于当前的代码块,定义在函数中的var变量不能被外部函数引用

  • 7.解构赋值
    首先来定义一个array看看:

    var array = ['A','B','C'];
    let [x,y,z] = array;/x = A,y=B,z=C
    let [,,z] = array;//z = c 
  • 在ES6中,可以使用解构赋值,直接对多个变量同时赋值.对数值元素进行解构赋值时,多个变量要用[...]括起来,有嵌套的情况下需要保持嵌套一致.同时赋值时还可以忽略***某些元素,如只对z进行赋值.

  • 若需要从一个对象中取出若干属性,也可以进行解构赋值,便于快速选取对象的指定属性:

    'use strict';
    var person = {
      name: 'a',
      age: 20,
      gender: 'male',
      passport: '12345678',
    };
    var {name, age, passport} = person;

    三个属性分别被相应的赋值

  • 还可以使用默认值避免不存在的属性返回undefined值

    //如果person对象没有single属性,默认赋值为true
    var {name, single=true} = person;
    name; // '小明'
    single; // true
  • 需要注意的是如果变量名和对象中的属性名不同的话,则返回undefined.如果要使用的变量名和对象属性名不同的话,则可以用如下获取:

    var person = {
      name: '小明',
      age: 20,
      gender: 'male',
      passport: '12345678',
    };
    // 把passport属性赋值给变量id:
    let {name, passport:id} = person;
    name; // '小明'
    id; // '12345678'
    // 注意: passport不是变量,而是为了让变量id获得passport属性:
    passport; // Uncaught ReferenceError: passport is not defined
  • 注意: passport不是变量,而是为了让变量id获得passport属(拿出来强调一下嘎嘎)

  • 应用场景:

1.交换x和y值,而不用写中间变量.

[x,y] = [y,x];

2.可以将对象的属性与参数直接绑定,便于直接进行相关的赋值

function buildDate({year,month,day}){
    return...
}
bulidDate({year:2107,month:11,day:11});

这里写的略显简单,待我补充
3.快速获取当前页面的域名和路径:

var {hostname:domain, pathname:path} = location;