函数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;