函数里面的数据都是局部变量,执行完会自动销毁
1. 函数定义
js函数是通过function关键字定义的
2. 函数声明
被声明的函数不会立即执行,它们被“保存以供后来使用”
2.1 自定义函数
function sum(a,b){
//函数体
return a + b;
}
2.2 函数表达式
var x = function fnname(a,b){
return a + b
}
//function后面可以加函数的名字,但是这个名字只能在函数内部使用
2.3 构造器方式
var a = new Function();
3. 函数提升(变量提升)
3.1 什么是提升?
简单的说就是js代码在执行前,引擎会先进行预编译,预编译期间会把变量声明和函数声明提升到其对应作用域的顶端
3.2 变量提升
全局作用域中声明的变量会提升至全局的最高层
函数内声明的变量会提升至函数的最顶层
注意:只提升声明,不会提升变量
//提升前
conole.log(a);
var a = 10;
//提升后
var a;
console.log(a);
a = 10;
//输出:10
3.3 函数提升
直接上图理解
注意:函数提升>变量提升
只提升声明,不提升变量
3.3.1 案例1
var a = true;
foo();
function foo(){
if(a){
var a = 10;
}
console.log(a);
}
//提升后
function foo(){
if(a){
a = 10;
}
console.log(a);//undefined
}
var a;
a = true;
foo();
3.3.2 案例2
//提升前
var a = true;
foo();
var foo = function () {
if (a) {
var a = 10;
}
console.log(a)
}
//提升后
var foo;
var a;
a = true;
foo();
foo = function () {
var a;
if (a) {
a = 10;
}
console.log(a);//TypeError:foo is not a function
}
3.3.3 案例3
//提升前
foo();
function foo() {
console.log('1');
}
var foo = function(){
console.log('2');
}
//提升后
function foo() {
console.log('1');
}
var foo;
foo();
foo = function () {
console.log('2')
}
//输出:1
4. 函数的调用
函数被定义时,函数内部的代码不会被执行
函数在调用的时候,函数内部的代码才会被执行
函数调用的时候,会先压入函数栈(保存函数调用过程中所有变量)
当函数调用结束之后,弹出函数栈(释放函数的所有变量)
4.1 直接调用
function sum(a, b){
return a + b;
}
console.log(sum(1,2))//3
4.2 链接调用
<a href="javascript:fn()"></a>
4.3 事件中调用
li[index].onclick = function(){}
4.4 对象的方式
var o = {
say:function(){
console.log('白敬亭好帅');
}
}
o.say();
4.5 构造函数的调用
function Star(){}
new Star();
4.6 定时器函数
setInterval(function(){
console.log('白敬亭冲呀')
},1000) //这个函数是定时器自动1秒中调用一次
4.7 立即执行函数
(function(){
console.log('李现')
})()
4.8 递归调用
定义:在函数内部调用函数本身
function fn(n) {
if (n == 1) return n;
return n * fn(n - 1)
}
console.log(fn(3));//6
//拆解
function fn(3) {
if (3 == 1) return n; // false
return 3 * fn(3 - 1) // 这个是fn(3)的结果
}
// 此时得到 3 * fn(2)
function fn(2) {
if (2 == 1) return n; // false
return 2 * fn(2 - 1) // 这个是fn(2)的结果
}
// 此时得到 3 * 2 * fn(1)
function fn(1) {
if (1 == 1) return n; // true 这个是fn(1)的结果
return n * fn(n)
}
// 此时得到 3 * 2 * 1 = 6
5. 箭头函数
5.1 基本介绍
ES6新增的一种函数的简写方式
5.2基本使用
什么时候使用?
当我们想要把一个函数作为参数传递给一个另一个函数里面的时候
//1.箭头函数写法
const fn = (a,b)=>{
return a + b;
}
console.log(fn(1,2))//3
//2.当箭头函数中,函数体只有一句代码,且返回值就是执行结果,可以省略{}
const fn = (a, b) => a + b;
console.log(fn(1,2));//3
//3.当形参只有一个时候,()也可以省略
const fn = v => v;
5.3 this的指向问题
5.3.1 普通函数中的this
- this总是代表它的直接调用者(js的this是执行上下文),例如obj.name(),那么name里面的this指向obj
- 正常情况下(非严格模式,‘use strict’),没有找到直接调用者,this指向全局window
例如:setTimeOut里面的this指向window - 在严格模式下,没有直接调用者的函数,this是undefined
- 使用call, apply, bind(ES5新增)绑定的this指向的是绑定的对象
5.3.2箭头函数中的this
- 箭头函数没有自己的this,它的this是继承而来,默认指向定义它是所处的对象,而不是执行它时候的对象
const ccc = {
ddd(){
setTimeout(function(){
setTimeout(function () {
console.log(this); //window
});
setTimeout(()=>{
console.log(this); //window
})
})
setTimeout(()=>{
setTimeout(function () {
console.log(this); //window
});
setTimeout(()=>{
console.log(this); //{ddd:f}----obj对象
})
})
}
}
6. 函数方法
6.1 toString()方法
6.2 call()方法
- 调用函数
- 改变this的指向
var o = {
name:'李现'
}
function fn(a,b){
console.log(this);//Object,此时this的指向发生了变化
console.log(a + b);//3
}
fn.call(o,1,2);
- call的主要作用是实现继承
function Father(uname,age,sex){
this.uname = uname;
this.age = age;
this.sex = sex;
}
function Son(uname,age,sex){
Father.call(this,uname,age,sex)
}
var son = new Son("白敬亭",20,"男");
console.log(son);//Son{age: 20 sex: "男" uname: "白敬亭" ···}
6.3 apply()方法
- 调用函数
- 改变函数内部this的指向
- 参数必须是伪数组