JavaScript之函数

三、函数

目录:函数的定义和参数获取、变量的作用域 let const详解、方法的定义和参数的获取

1.函数的定义和参数获取

例:创建绝对值函数
1)定义函数
①定义方式一

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

一旦1执行到return代表函数结束,返回结果。
如果没有执行到return,函数执行完也会返回结果,结果为undefined。
②定义方式二

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

function(x){……}这是匿名函数,但是可以把结果赋值给abs。通过abs就可以调用函数,相当于Java的匿名内部类。
2)调用函数

abs(10)
abs(-10)

参数问题:JavaScript可以传任意个参数,也可以不传递参数。
参数进来是否存在的问题如何解决?
假设不存在参数如何规避?

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

3)arguments
arguments是JS免费送的关键字,能获取传递进来的所有参数,是一个数组。

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

问题:arguments包含所有的参数,有时候想使用多余的参数来进行附加操作,需要排除已有参数。
4)rest:ES6引入新特性,获取除了已经定义的参数之外的所有的参数。
以前

if(arguments.length>2) {//如果定义了2个参数
  for(var i=2;i<arguments.length;i++) {…}
}

现在

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

rest参数只能写在最后面,必须用…标识。有点像Java的可变长参数。

2.变量的作用域、let、const详解

1)在JavaScript中,var定义变量实际是有作用域的。
假设在函数体中声明,则在函数体外不可使用(非要想实现可以用闭包)。

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

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

function f1() {
  var x=1;
}
function f2() {
  var x='A';
}

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

function f() {
  var x=1;
  function f3() {
    var y=x+1;//2
  }
  var z=y+1;//Uncaught ReferenceError: y is not defined
}

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

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

假设在JavaScript中函数查找变量从自身函数开始,由“内”向“外”查找,假设外部存在这个同名的函数变量,则内部函数会自动屏蔽外部函数的变量。
2)提升变量的作用域

function f() {
  var x="x"+y;
  console.log(x);
  var y="y";
}

结果为xundefined。
说明:js执行引擎,自动提升了y的声明,但是不会提升变量y的赋值。
上例等同于:

function f() {
  var y;
  var x="x"+y;
  console.log(x);
  y="y";
}

这个是在JavaScript建立之初就存在的特性。
规范:所有的变量定义都放在头部,不要乱发,便于代码维护。
3)全局变量
全局对象window

var x="xxx";
window.alert(window.x);//默认所有的全局变量,都会自动绑定在window对象下

alert()这个函数本身也是一个window变量。

var x="xxx";
window.alert(x);
var old_alert=window.alert;
//old_alert(x);
window.alert=function() {
};
window.alert(123);//123没有弹出,发现alert()失效了
//恢复
window.alert=old_alert;
window.alert(456);//弹出456

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

//唯一全局变量
var win={ }
//定义全局变量
win.name= "xiaoming";
win.add=function(a,b) {
  return a+b;
}

把代码全部放入定义的唯一空间名字中,降低全局命名冲突问题。
jQuery库把所定义的都放到jQuery中,并用简化符$()。
5)局部作用域let

function aa() {
  for(var i=0;i<100;i++) {
    console.log(i);
  }
  console.log(i+1);//101
}

问题:i出了这个作用域还可以使用。
ES6中let关键字,解决局部作用域冲突问题。

function aa() {
  for(let i=0;i<100;i++) {
    console.log(i);
  }
  console.log(i+1);//Uncaught ReferenceError: i is not defined
}

建议使用let去定义局部作用域的变量。
6)常量const
在ES6之前,怎么定义常量:只有用全部大写字母命名的变量就是常量,建议不要修改这样的值。

var PI='3.14';//可以改变这个值

在ES6引入了常量关键字const

const PI='3.14';
PI='123';//TypeError: Assignment to constant variable

3.方法的定义和参数获取

1)定义方法
方法就是把函数放在对象里面,对象只有两个东西,就是方法和属性。

var ming = {
  name: 'xiaoming',
  birth: 2001,
  //方法
  age: function() {
    var now = new Date().getFullYear();
    return now-this.birth;
  }
}
//调用属性
ming.name
//调用方法,一定要带()
ming.age()

this.代表什么?
拆开上面的代码来看。

var ming = {
  name: 'xiaoming',
  birth: 2001,
  //方法
  age: getAge
}
function getAge() {
    var now = new Date().getFullYear();
    return now-this.birth;
}
ming.age();//20
getAge();//NaN,单独使用,使用window对象,没有birth属性
}

this是无法指向的,是默认指向调用它的对象。
2)apply
在js中可以控制this指向。

getAge.apply(ming,[]);//this指向ming,参数为空。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • JavaScript函数 1.函数格式 function 函数名称(形参列表){​ return x;...
    煤球快到碗里来阅读 1,391评论 0 1
  • 函数 函数定义与调用 定义函数的方式如下: 第一种定义:function指出这是一个函数定义;函数体内部的语句在执...
    DramaScript阅读 2,844评论 0 0
  • 函数 函数是专门用于封装代码的,函数是一段可以随时被反复执行的代码块 函数的格式 不使用函数的弊端 冗余代码太多 ...
    遇明不散阅读 2,241评论 0 0
  • 什么是函数 函数是专门用于封装代码的,函数是一段可以随时被反复执行的代码 函数的格式 使用函数的优点: 减少冗余代...
    风暴java之灵阅读 2,607评论 0 2
  • 推荐指数: 6.0 书籍主旨关键词:特权、焦点、注意力、语言联想、情景联想 观点: 1.统计学现在叫数据分析,社会...
    Jenaral阅读 11,002评论 0 5