函数

定义函数(也就是方法)

定义方式一

绝对值函数

function abs(x){
   if(x>=0){
   return x;
   }else{
   return -x;
   }
}

一旦执行到return就代表函数结束了,并返回结果。
如果没有执行return,函数执行完也会返回结果,结果是undefined

定义方式二

var  abs  =  function(x){
   if(x>=0){
   return x;
   }else{
   return -x;
   }
}

function(x){…} 这是一个匿名函数,但是可以把结果赋值给abs,通过abs就可以调用函数!

调用函数

abs(10)   //10
abs(-10)  //10

参数问题:JavaScript可以任意个参数,也可以不传参数
假如不存在参数,如何规避?

function abs(x){
  //通过手动抛出异常来判断
   if(typeof x!=='number'){
      throw 'Not a Number';
   if( x>=0){
   return x;
   }else{
   return -x;
   }
}

arguments 是js上面的一个关键字;
代表,传递进来的所有的参数是一个数组

var  abs  =  function(x){
   console.log("x=>"+x);
   for(var i = 0;i < arguments.length;i++){
    console.log(argument[i]);
  }
   if(x>=0){
   return x;
   }else{
   return -x;
   }
}

问题:arguments 包含所有的参数,我们有时候想使用多余的参数来进行附加操作。需要排除已有参数

rest
ES6引入的新特性,获取除了已经定义的参数之外的所有的参数

以前:

if(arguments.length>2)
   for(var i = 2;i< arguments.length; i++){
     //...
   }
}

ES6引入的新特性,获取定义的参数之外的所有参数

function aa(a,b,...rest){
   console.log("a=>"+a);
   console.log("b=>"+b);
   console.log(rest);
}

rest 参数只能写在最后面,必须用。。。标识。

变量的作用域

在js中,var定义变量实际是有作用域的。
假设在函数体中声明,则在函数体外不可以使用(非要想实现的话,后面可以研究“闭包”)

function qw(){
   var x = 1;
   x = x + 1;
}
x=x+2;   //Uncaught ReferenceError:x is  not  defined

如果两个函数使用了相同的变量名,只要在函数内部就不冲突

function qw1(){
   var x = 1;
   x = x + 1;
}
function qw2(){
   var x = ‘a’;
   x = x + 1;
}

内部函数可以访问外部函数的成员,反之则不行

function qw(){
   var x = 1;
   function qw1(){
   var y = x+1;    //2
}
  var z = y + 1;   //出错
}

假设内部函数变量和外部函数的变量重名

function qw(){
   var x = 1;
   
   function qw1(){
   var x = 'A';    //
   console.log('inner'+x);  //innerA
}
  console.log('outer'+x);  //outer1
  qw1()
}
qw()

假设在js中 函数查找变量从自身函数开始,由内向外查找。假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量(类似于C语言)

提升变量的作用域

fuction qw(){
  var  x="x"+y;
  console.log(x);
  var y='y';
}

结果:xunderfined
说明:js执行引擎,自动提升了y的声明,但不会提升变量y的赋值,相当于将var y;放到了前面,而没给y赋值。
所以要养成规范:所有的变量定义都放在了函数头部,不要乱放,便于代码维护,用的时候直接在后面赋值;

function qw(){
  var  x,
         y=1,
         z,a,t;


   z=2;
}

全局变量

在函数外面直接定义 var x=‘A’;

JS实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错RefrenceError

规范

由于我们所有的全局变量都会绑定到我们的window上。如果不同的js文件,使用了相同的全局变量,就会冲突

//自己定义一个唯一的全局变量
var  Bai = {}

// 定义全局变量
Bai.name = 'baixiaobai'
Bai.add = function(a,b){
   return  a  +  b ;
}

把自己的代码全部放在自己定义的唯一空间名字中,降低全局命名冲突的问题

局部作用域 let

function  aa(){
  for(var i=0;i<100;i++){
        console.log(i)
    }
    console.log(i+1);  // i 出了这个作用域还可以使用,这是一个问题
}

ES6 let关键字,解决局部作用域冲突问题

function  aa(){
  for(let i=0;i<100;i++){
        console.log(i)
    }
    console.log(i+1);  // 报错
}

建议使用let去定义局部作用域的变量

常量const

const  PI = 3.14;   // 他变成只读的了,无法进行修改

方法(js中把函数放在对象里)

方法就是把函数放在对象的里面,对象只有两个东西:属性和方法

<script>
   var  xiaobai = {
  name:‘白小白’,
  birth:1999,
  // 方法
  age:function (){
        var  now  = new  Data().getFullYear();
        return  now-this.birth;
    }
}
</script>
调用:
//属性
xiaobai.name
//方法,一定要带()
xiaobai.age()

this 始终是指向调用他的对象

将上述的代码拆开查看

function  getAge(){
   //今年-出生的年
   var now = new Date().getFullYear();
   return now-this.birth;
 }

 var xiaobai = {
   name:'白小白',
   birth:1999,
   age:getAge
}

//xiaobai.age()     这会运行成功
//getAge()      这不会成功 返回NaN,因为此时的this指向的是window

apply

在js中可以控制this指向!

function  getAge(){
   //今年-出生的年
   var now = new Date().getFullYear();
   return now-this.birth;
 }

 var xiaobai = {
   name:'白小白',
   birth:1999,
   age:getAge

 var dahei = {
   name:'黑大黑',
   birth:1999,
   age:getAge


  //getAge.apply(xiaobai,[]);  //此时this指向了xiaobai,参数为空