JavaScript 函数详解
1 定义函数与函数调用
定义方式一
绝对值函数
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
2 参数获取
参数问题:JavaScript可以传任意个参数,也可以不传参数。
手动抛出异常,规避无参数问题
function abs(x){
if (typeof x!=='number'){
throw 'Not a Number';
}
if (x>=0){
return x;
}else{
return -x;
}
}
测试结果:
arguments关键字
arguments一个js免费赠送的关键字;代表传递进来的所有的参数是一个数组。
测试代码:
function abs(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;
}
}
测试结果:
rest 参数
rest参数类似于Java中的"…",用于接收除了特定参数之外剩余的所有参数,组成为一个数组。
测试代码:
function fun(a,b,...rest) {
console.log("a=>"+a);
console.log("b=>"+b);
console.log(rest);
}
测试结果:
注意:rest参数只能写在最后面,使用"…rest"标识。
3 变量的作用域
在JavaScript中,var定义的变量是有作用域的。
在函数体中声明,在函数体外不可以使用。
'use strict';
function f() {
var x = 1;
x = x + 1;
}
x=x+2; //Uncaught ReferenceError: x is not defined
同时,内部函数成员可以访问外部函数的成员,反之则报错。
假设内部函数变量和外部函数的变量重名,从自身函数开始由‘内’向‘外’查找,假设外部存在一个相同的变量,则内部屏蔽外部变量。
提升变量的作用域
function f() {
var x = 'x' +y;
console.log(x);
var y = 'y';
}
f();
结果:xundefined
说明:js执行引擎,自动提升y的声明,但是不会提升变量y的赋值。
为了更好代码维护,将所有变量的定义放置在头部。
全局变量
将变量定义在函数外部,则声明周期是整个线程。
'use strict'
// 全局变量
var x = 1;
function f() {
console.log(x);
}
f();
console.log(x);
//测试结果:
1
1
JavaScript实际上只有一个全局作用域,任何变量(函数也可以视作变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错RefrenceError
规范
由于所有的全局变量均会绑定到window上,如果不同的js文件,使用了相同的全局变量,就会引发冲突,所以,如何能够减少冲突?
'use strict'
//唯一全局变量;
var DemutApp = {};
//定义全局变量
DemutApp.name = 'Demut';
DemutApp.add = function (a,b) {
return a+b;
}
把自己的代码全部放到自己定义的唯一空间名字中,解决全局命名,冲突的问题。
局部作用域let
请看👇问题:
测试代码:
function f() {
for (var i = 0; i < 10; i++) {
console.log(i);
}
console.log(i+1); //正常情况下i不可以被使用,而此处确可以
}
f();
运行结果:
故为解决局部作用域冲突问题,在ES6中引入了let关键字。
故将以上for循环中var
改为let
后,回归正常。结果如下:
建议以后使用let
定义局部作用域的变量。
常量const
在ES6之前,使用全部大写字母命名的变量,称为常量,建议不要修改这样的值。
var PI = '3.14';
console.log(PI);
PI = '213'; //值是可以改变的,只是约定不改变
console.log(PI);
这种约定的方法确实不规范,所以ES6引入const
关键字,规范以上问题。
const PI = '3.14';
console.log(PI);
PI = '213'; //报错
console.log(PI);
4 方法
定义方法
方法就是把函数放在对象的里面,对象只有两个东西:属性和方法。
var Demut = {
name:'demut',
birth: 2000,
//方法:
age: function () {
//今年-出生年
var now = new Date().getFullYear();
return now - this.birth; //this指向本对象
}
}
//属性
Demut.name
//方法,一定要带()
Demut.age()
运行结果:
以上代码有另一种表示:
function getAge() {
//今年-出生年
var now = new Date().getFullYear();
return now - this.birth;
}
var Demut = {
name:'demut',
birth: 2000,
//方法:
age: getAge()
}
//Demut.age() => 20
//getAge() => NaN
说明:getAge()中的this只能指向调用它的那个对象,如果没有对象,则默认指向window,window中没有birth属性,故返回NaN。
在Java中this
是严谨的,只能指向本对象,但在Javascript中,可以使用apply
控制this
的指向。以下介绍apply:
apply
在js中apply可以控制this的指向。
测试代码:
//代码同上,在浏览器控制台中输入以下代码
getAge.apply(Demut,[]) //this指向Demut, []表示传入参数为空
运行结果:
写在最后
又如鹰搅动巢穴,在雏鹰以上两翅搧展,接取雏鹰,背在两翼之上。
——申命记32:11To Demut and Dottie!