JavaScript(5)函数

目录

函数

函数声明提前

函数内部属性

arguments

this的指向

显式函数绑定

IIFE

作用域

作用域链

什么是自由变量

什么是作用域链

闭包案例 经典面试题


函数: 允许封装一系列代码,当想要完成某一任务时,只需要调用相应的代码即可。

函数

// 函数声明
function 函数名(形参列表){
    函数体
    return 返回值;
//  return 后面的代码就不会生效了
}

//或者也可以通过下列的方式进行定义函数

//函数表达式
var 函数名 = function(形参列表){
    函数体
    return 返回值;
//  return 后面的代码就不会生效了
}

函数声明提前

函数也是有变量声明提前的

// 函数也是有变量声明提前的
fpp(20000); //我是函数fpp20000
function fpp(a){
  console.log('我是函数fpp' + a);
}

fpp(10000); //我是函数fpp10000

//基本等于

function fpp(a){
    console.log('我是函数fpp' + a);
}
fpp(20000);
fpp(10000);

函数内部属性

arguments

当传递的实参超过形参的个数的时候 不会报错 所有的实参都会保存在 arguments 里 arguments类数组

function foo(a, b){
  console.log(arguments);
  console.log(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]); // 1 2 3 4 5
  return console.log(a, b)
}

foo(1, 2, 3, 4, 5) // 1 2
// 获取一个函数形参的长度
console.log(foo.length) // 2

callee 属性是 arguments 对象的一个成员,当前相关函数正在执行时才可使用

callee 属性的初始值就是正被执行的 Function 对象。

// 实现匿名的递归函数
var sum = function (n) {
  if (n == 1) {
      return 1;
  } else {
      return n + arguments.callee(n - 1);
  }
}
console.log(sum(6));//输出结果:6+5+3+2+1 = 21

this的指向

面向对象语言中this的指向,都是指向当前调用的对象

然而在JavaScript中不同,this的指向随着环境的变化而变化

1.在函数中this指向全局对象 global window
2.在对象中 this指向拥有该方法得调用者
3.在当前模块 this指向当前模块 {}
4.事件:this指向接收事件得dom元素

function test(){
  console.log(this);
};
test(); // 局部作用域  -> 指向的就是全局对象 global

let obj = {
  name:'zhangsan',
  age:18,
  say(){
    console.log(this.name);
  }
}
obj.say()//this 表示该方法所属的对象

console.log(this); //全局作用域 -> modules.export {}

<script>
    //在浏览器环境下 this单独使用 指向的就是window对象
    //Window file:///F:/this.html
    console.log(this);
</script>

显式函数绑定

在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。

// 显式函数绑定this
// call apply
// call() 方法分别接受参数 apply() 方法接受数组形式的参数
var person1 = {
  sayName: function(a){
    console.log(this.name + a);
  }
};
person1.sayName(); //NaN

var person2 = {
  name:'lisi'
};
person1.sayName.call(person2); // lisiundefined
person1.sayName.call(person2, 123); // lisi123
person1.sayName.apply(person2); // lisiundefined
person1.sayName.apply(person2,[123]); // lisi123

IIFE

IIFE立即执行函数,Immediately Invoked Function Expression,意为立即调用的函数表达式。

作用:

1.页面加载完成后只执行一次的设置函数。

2.将设置函数中的变量包裹在局部作用域中,不会泄露成全局变量。

普通函数调用和IIFE函数调用

//普通函数
function foo(){
  console.log('1');
}
foo();

//IIFE函数
(function foo(){
  console.log('1');
})();

经典面试题-IIFE

for (var i = 0; i < 6; i++) {
  function output() {
    console.log(i); // 为什么输出的是6,而不是0,1,2,3,4,5
    // 因为输出的 i 是全局作用域的,当循环结束后 i 的值是 6,所以输出的 i 就是6。
  }
}
output()
for (var i = 0; i < 6; i++) {
  (function (j) {
    console.log(j); //0,1,2,3,4,5
  })(i)
    // 因为 JS 中调用函数传递参数都是值传递 ,
    // 所以当立即执行函数执行时,首先会把参数 i 的值复制一份,
    //然后再创建函数作用域来执行函数,循环5次就会创建5个作用域,
    //所以每个输出访问的都是不同作用域的 i 的值 。
}

需要IIFE的原因:JS只有全局作用域和函数作用域,通过立即执行函数隔离作用域。杜绝作用于对于函数的影响。

作用域

ES5中

函数作用域: 在 JavaScript函数中声明的变量,会成为函数的局部变量。

                       函数内部声明的变量,在函数外部不能访问。

全局作用域:函数之外声明的变量,会成为全局变量。

                      函数外部声明的变量,在函数内部可以访问。

                      当函数嵌套,在这个时候,内部函数与外部函数的这个变量就组成了闭包。

//全局作用域:global/window/本文件内
var a = 10;
b = 20; // 所有末定义直接赋值的变量自动声明为拥有全局作用域
function foo() {
  //函数作用域、局部作用域
  var c = 3;
  console.log(a, b); 
  console.log(this);
}
foo()
// console.log(c); // a is not defined

作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突

作用域链

什么是自由变量

当前作用域没有定义的变量,这就是自由变量 。

下列代码中的a变量就是自由变量

var a = 1;
function foo(){
    console.log(a); //1
    var b = 2;
    console.log(b); //2
}
foo();

什么是作用域链

当前作用域中找不到所需要的变量,就向上一层中寻找,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是作用域链 。

var a = 1;
function foo(){
    var b = 2;
    function fn(){
      var c = 3;
      console.log(c); // 3
      console.log(b); // 2
      console.log(a); // 1 如果foo函数中有定义变量a 该打印就会打印foo中的变量a
    }
    fn();
}
foo();

闭包案例 经典面试题

var a = 10
function fn() {
  var b = 20
  function bar() {
    console.log(a + b) //30
  }
  return bar
}
var x = fn(); // 执行fn() 返回的是bar
b = 200;
x() //执行x,就是执行bar函数 10+20
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值