函数的定义和调用
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()来访问修改
好啦,就到这里!