JavaScript函数详解

函数的定义和调用

1.函数的一般格式

function sum(a,b){
	return a+b;
}
sum(1,2);//3

2.函数表达式(匿名函数)

var c= function(a,b){
	return a+b;
};
// 函数表达式可以保存到变量中,通过变量名来调用
console.log(c(1,2));// 3 

3.构造函数

var fct1 = new Function("a","b","return a+b");
console.log(fct1);//打印输出一个函数,如下图
console.log(fct1(1,2));//3

//等同于
var fct2 = function(a,b){
	return a+b;
}

在这里插入图片描述

4.自调用函数

函数表达式可以 “自调用”。
自调用表达式会自动调用。
如果表达式后面紧跟 () ,则会自动调用。
不能自调用声明的函数。
通过添加括号,来说明它是一个函数表达式:

//自调用函数
 var a(function ptr(){
     console.log("hello!");
 })();
 //控制台输出打印hello,注意我们并未调用它

//匿名自调用函数
var c=(function (){
	console.log("hi");
})();

5.箭头函数

ES6新增了箭头函数 ,其格式为

(参数列表)=>{ 函数声明 }
等同于
(参数1,参数2,参数3....)=>{ return 表达式 }
当只有一个参数时,参数外面的括号可有可无。(参数)=>{ 函数声明 }或者参数=>{ 函数声明 }
当没有参数时,写成一对圆括号()=>{ 函数声明 }

//示例
//ES6
let sum1 = (x,y)=>x + y;
console.log(sum1(1,2));//3
//ES5
var sum2 = function(x,y){
return x+y;
}
console.log(sum2(1,2));//3

6.Javascript 严格模式

使用"use strict"指令,在严格模式下不可以使用未声明的变量,(JS实在是太随意了).

"use strict"
console.log(a);// Uncaught ReferenceError: a is not defined
a = 3.14;
console.log(a);// Uncaught ReferenceError: a is not defined

在这里插入图片描述
使用 use strict ,在编辑器中也会提示相关错误。
在这里插入图片描述
其中a变量是未声明类型,b变量中的灰色虚线则是var类型不建议使用,使用let,或者const(转为常量)。

7.对象中的方法–函数

绑定到对象上的函数称为方法,和普通函数没啥区别,但是它在内部使用了一个this关键字.

 "use strict"
 var xiaoming = {
     name: '小明',
     birth: 2001,
     age: function () {
         var y = new Date().getFullYear();
         return y - this.birth;
     }
 };
 xiaoming.age; // function xiaoming.age()
 xiaoming.age(); // 21

等同于

 function getAge() {
     var y = new Date().getFullYear();
     return y - this.birth;
 }

 var xiaoming = {
     name: '小明',
     birth: 2001,
     age: getAge
 };

 xiaoming.age(); // 21, 正常结果
 getAge(); // NaN
apply()方法 和call()方法

通过apply()方法或者call()方法,将this引用到指定对象。
当需要传递参数时,call可以直接写多个参数,apply需要用数组方式传递(它俩默认第一个参数都是this引用的对象)。

function getAge() {
    var y = new Date().getFullYear();
       return y - this.birth;
}

var xiaoming = {
    name: '小明',
    birth: 2001,
    age: getAge
};

xiaoming.age(); // 21, 正常结果
getAge(); // NaN
getAge.apply(xiaoming,[]);//通过 apply 可以指定this 指向某个对象,参数列表为空 打印输出 21
getAge.call(xiaoming);//通过call 可以指定this 指向某个对象21

this就是当前对象自身的指代。

函数参数

显示参数和隐式参数(arguments)

参数规则:
1.JavaScript 函数定义显式参数时没有指定数据类型。
2.JavaScript 函数对隐式参数没有进行类型检测。
3.JavaScript 函数对隐式参数的个数没有进行检测。

arguments对象

arguments对象,Javascript免费赠送的一个关键字(皮一下),arguments对象中包含了函数调用的形参数组。

既然它是形参数组,就表示它应该有任意多个。

//来试试找一个隐式参数的最大参数值
 "use strict"
 function getmax(){
      let max;
      max = arguments[0];
      for(let i =0;i<arguments.length;i++){
          if(max<arguments[i+1]){
              max = arguments[i+1];
          }
      }
      console.log("max:"+max);
  }
  getmax(8,11,7,2,3);//11

然后显示参数的话,就是正常的那样,需要注意的是ES6中,形参可以有初始值(默认值)。

可变参数…rest

 "use strict"
 function getAll(a,b,...rest) {
     console.log("a:"+a);
     console.log("b:"+b);
     console.log(rest)
 }

在这里插入图片描述

显示参数,形参默认值(ES6)

"use strict"
function sum(x,y=100){
	return x+y;
}
sum(1);//101
sum(2,3);//5

Javascript闭包(重点)

先来看两个例子,函数既可以访问内部变量,又可以访问外部变量。

 "use strict"
 // 函数可以访问由函数内部定义的变量
 function sum() {
     var a =4;// 局部变量
     return a+a;
 }
 console.log(sum());//打印8
 //函数也可以访问函数外部定义的变量
 var b=4;//类似全局变量,web页面中全局变量window对象\
 console.log(b);
 function sub1() {
     return b-1;
 }
console.log(sub1())

如果内部变量和外部变量重名的话,访问函数内部的变量,且内部变量不会修改外部变量(局部变量不会修改全局变量);

"use strict"
var a =8;
function rem() {
    var a =10;
    return a*a;
}
console.log(a);//外部a 8
console.log(rem());//100

全局变量的作用域是全局性的,即在整个JavaScript程序中,全局变量处处都在。而在函数内部声明的变量,只在函数内部起作用。这些变量是局部变量,作用域是局部性的;函数的参数也是局部性的,只在函数内部起作用。

闭包就是为了封装一个私有变量,在Java中可以通过类和private修饰成员变量来实现,但是JS中并没有类只可以通过闭包来实现。

经典计数器counter()

//counter 通过函数访问外部变量来计数
var counter = 0;
function count(){
	counter = counter+1;
	return counter;
}
count();//1
count();//2
count();//3
//貌似很正常?不,实际上很不安全,你可以在外部任意的修改counter的值
counter = 0;// 0 counter被非法修改,那如果我放到函数的内部呢?
count();//1 此处原本应该是4!
"use strict"
//counter 通过函数访问内部变量来计数
function count(){
	var counter = 0;
	counter +=1;
	return counter;
}
count();//1
count();//1
count();//1
//由于每次调用count()函数,都将counter的初值设为了0,所以无论调用多少次都只能是1
// 看到这里,不禁又怀念起了对象,类,私有属性对吧?

那么如何实现,安全的计数器呢?
在JavaScript中,可以函数嵌套函数,并且嵌套函数可以访问上一层的函数变量。

"use strict"
function count(){
	var counter = 0;
	function add(){
		counter +=1;
	}
	add();
	return counter;
};
count();// 1
count();// 1 每次调用时,函数还是会将counter 初值设置为0
// 只要能在外部访问add()便可以实现安全的计数器
 "use strict"
 var ct=(function count(){
     var counter = 0;
     return function add(){ console.log(counter+1);return counter+=1}
 })();//0 自调用函数,执行一次,将counter值设为0
 ct();//1
 // counter=0; 在严格模式下 counter=0;属于未定义会直接报错
 ct();//2 
 ct();//3

ES6 箭头函数的闭包?(如下)

"use strict"
var ct=( () => {
     var counter = 0;
     console.log(counter);
     return () => { console.log(counter+1);return counter+=1};
 })();
 ct();//1
 ct();//2
// counter=0; 在严格模式下 counter=0;属于未定义会直接报错
 ct();//3 counter的访问只能通过ct()来访问修改

好啦,就到这里!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杀死一只知更鸟debug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值