Javascript函数
创建函数
let no=new Function('name','console.log(name)');//第一个是参数,第二个是执行过程
no('不忘')//不忘
function no(name) {
console.log(name);
}n
no('不忘')//不忘
对象里面的函数,又叫方法
let no={
getName:function(name){
console.log(name);
}
}
no.getName('不忘')//不忘
let no={
getName(name){
console.log(name);
}
}
No.getName('不忘')//不忘
匿名函数
let no=function(name){//这样的就是匿名函数,将函数放在变量No里
console.log(name);
}
no('不忘')//不忘
自执行函数
;(function(name) {
console.log(name+'很帅');
})('不忘')//不忘很帅
//会自动执行,不需要调用,以前用于划分函数,可以防止用同一个函数名而出现错误
函数提升
no('不忘')//不忘有很多老婆
function no(name) {
console.log(name+'有很多老婆');
}
no('不忘')//不忘有很多老婆
//函数定义后可以在函数前面调用
参数
形参和实参
function no(name) {//name就是形参,表示要接受参数,取一个能明白的单词就好
console.log(name+'有很多老婆');
}
no('不忘')//不忘有很多老婆 //'不忘'这个字符串就是实参,要传进去的实际参数
默认参数
function no(name="不忘") {//这时候没有实参传过来时就会默认字符串"不忘"
console.log(name+'有很多老婆');
}
no()//不忘有很多老婆
arguments查看参数
function no(arr) {
console.log(arguments);
console.log(arguments.length);
}
no(1,2,3,4,5)//[1,2,3,4,5] 5
//这里生成的时候个伪数组,有数组一部分的特性,用来看当实参个数不确定的情况,后面多用扩展运运算符
箭头函数
基础用法
let no=(name="不忘")=>{
console.log(name+'有很多老婆');
}
no()//不忘有很多老婆
简写
let arr=[1,2,3,4,5,6,7,8,9,10].filter(value => value%2==0)//只有一个参数时可以去掉阔话,当返回值只有一行表达式时可以去掉return,写在同一行
console.log(arr);//[2, 4, 6, 8, 10]
回调函数
在其他函数调用的函数,叫做回调函数
let arr=[1,2,3,4,5,6,7,8,9,10].filter(value => value%2==0)//这里面的函数就是filter的回调函数
console.log(arr);//[2, 4, 6, 8, 10]
this
在function这东西就像称谓里面的我,谁用的的指向谁
let no={
name:'不忘',
girls(){
console.log(this.name+'的女朋友是冰冰');
}
}
no.girls()//不忘的女朋友是冰冰
在箭头函数里指向所在的环境
let no={
name:'不忘',
girls:()=>{
console.log(this.name+'的女朋友是冰冰');
}
}
window.name='window下的不忘';
no.girls()//window下的不忘的女朋友是冰冰
//环境在全局环境中,在浏览器全局环境是window,所以指向window的name
常量改变this指向
let no={
name:'不忘',
girls(){
let that=this //将this指向that
function see() {
console.log(that.name+'的女朋友是冰冰');//这里this已经不是指向no了,因为see函数不是no调用的,所以用that
}
see()
}
}
no.girls()//不忘的女朋友是冰冰
构造函数里面的this
function Man(name) {
this.name = name;
}
console.log(new Man('不忘'));//Man {name: "不忘"} //这是一个Man对象
改变this指向的方法
call
function see(one,two) {
console.log(this.name+'女朋友是'+one+','+two);
}
let no={
name:'不忘'
};
see.call(no,'冰冰','嘉嘉')//不忘女朋友是冰冰,嘉嘉
//第一个参数是指向的对象,后面是进来是参数,立即执行
apply
function see(one,two) {
console.log(this.name+'女朋友是'+one+','+two);
}
let no={
name:'不忘'
};
see.apply(no,['冰冰','嘉嘉'])//不忘女朋友是冰冰,嘉嘉
//和call差不多,就是传过来的参数用数组
bind
function see(one,two) {
console.log(this.name+'女朋友是'+one+','+two);
}
let no={
name:'不忘'
};
see.bind(no,'冰冰','嘉嘉')()//不忘女朋友是冰冰,嘉嘉
//和call差不多,就是不立即执行需要调用一下
环境和作用域
什么是环境和作用域
这涉及一些函数执行的底层知识,大概可以理解为,你烧饭还要一个厨房,先要有地方才能干活。
函数执行在真实操作时也是需要’地方‘的,这就是环境和作用域。
最外面时全局作用域,函数的我们一般叫函数作用域(局部作用域),不同作用域互不影响。
函数运行过程会先创建作用域,执行,完毕后销毁作用域
闭包
基础情况
function one() {
let a=1
function two(){
console.log(a);
}
two()//执行two时会在one的作用域内创建一个作用域,本来两个作用域互不影响,但这里可以two的作用域在自己的作用域访问不到a变量的情况下可以访问到外部one作用域的a变量,这个可以访问外面作用域变量的情况叫做闭包,闭包不能访问外界作用域的this
}
one()//1
闭包的作用:延长变量是生命
function add() {a
let a=1
return function two(){
console.log(a++);
}
}
let change=add()
change()//1
change()//2
change()//3
//此时由于two函数被返回出来,所以add函数没有执行完成,就会导致add的作用域没有销毁,所以里面的a变量被保存下来了,当执行two函数的时候,由于闭包可以查询到a变量,所以a就会执行一次增加一次
构造函数的作用域
function Change() {
let a=1
this.add=function(){
console.log(a++);
}
}
let no=new Change();
no.add()//1
no.add()//2
no.add()//3
//new出来的对象也有这样如同闭包的效果
块级作用域
这是let和const才有用的东西
{
//块级作用域
let a=1
console.log(a);//1
}
{
//块级作用域
let a=2
console.log(a);//2
}
let a = 3
console.log(a);//3
//同一个作用域let不能用用一个变量名,在块级作用域里就在两个不同的作用域里了,while,if,for语句里也有块作用域