task27 进阶:JS 核心之函数!!!重要

  1. 函数的 5 种声明
  2. 如何调用函数 f.call
  3. this 和 arguments
  4. 什么是 call stack
  5. 作用域
  6. 闭包

如果你意犹未尽,可以查看我的《JS深入浅出》里讲的《函数》

函数的 5 种声明

  1. 具名函数

     function x(input1,input2){
         return input1+input2
     }
     x.name // 'x'
     console.log(x)  
     //如果x是字符串,直接打印x
     //如果x不是字符串,调用x.toString()
    

输入:x,y
返回:写在return后面,如果不写,自动return undefined


task27 进阶:JS 核心之函数!!!重要_第1张图片
image.png
  1. 匿名函数

     var f
     f = function(x,y){
         return x+y
     }
     f.name // 'f'
    
    

如果使用匿名函数,必须要把这个匿名函数赋值给一个对象

  1. 具名函数赋值

     var f
     f = function f2(x,y){ return x+y }
     f.name // 'f2'
     console.log(f2) // undefined
    
    
task27 进阶:JS 核心之函数!!!重要_第2张图片
image.png

task27 进阶:JS 核心之函数!!!重要_第3张图片
image.png
function y(){}
console.log(y)  //√
//刷新下页面
var x = function y(){}
console.log(y)  //× 报错
  • 面试中经常问第3种
  1. window.Function

     var f = new Function('x','y','return x+y')
     f.name // "anonymous"
    
var n=1
var f = new Function('x','y','return x+'+n+'+y')
f(1,2)  //返回结果是多少?4还是'1n2'?
task27 进阶:JS 核心之函数!!!重要_第4张图片
image.png
  1. 箭头函数

     var x = (x,y) => {
         return x+y
     }
     var sum = (x,y) => x+y 
     //如果{}里面只有一句话,且这一句话是return,
     //那么可以把{}和return一起去掉。必须一起去掉
     //等价于var sum = (x,y) => {return x+y} 
    
     var n2 = n => n*n
     //如果参数只有一个,()可以省略掉
    
    

函数的name属性

task27 进阶:JS 核心之函数!!!重要_第5张图片
image.png

如何调用函数

f.call(asThis, input1,input2)
其中 asThis 会被当做 this,[input1,input2] 会被当做 arguments
禁止使用 f(input1, input2),因为学会 .call 才能理解 this

  • 先了解下什么是函数?
    见阮一峰javascript函数这一章的概述

函数是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。

task27 进阶:JS 核心之函数!!!重要_第6张图片
image.png

task27 进阶:JS 核心之函数!!!重要_第7张图片
image.png

task27 进阶:JS 核心之函数!!!重要_第8张图片
image.png

eval()传的参数是一个字符串,eval将这段字符串当做代码执行
函数是一个对象,函数执行就是eval函数体的过程


task27 进阶:JS 核心之函数!!!重要_第9张图片
image.png

task27 进阶:JS 核心之函数!!!重要_第10张图片
image.png

f是这个对象,f.call()是执行这个函数的函数体

函数是一个对象,这个对象可以执行一段我们写的代码


task27 进阶:JS 核心之函数!!!重要_第11张图片
image.png
  • js有7种数据类型
  • 6种简单数据类型:number,string,boolean,undefined,null,symbol
  • 1种复杂数据类型Object,原型链中有Object.prototype的都是对象
  • Array,Function,Date,RegExp,Error等都属于Object类型,因为他们的原型链中有Object.prototype。
  • Array有自己独有的原型Array.prototype
  • Function有自己独有的原型Function.prototype
  • Function.prototype有三个很重要的方法:call() apply() bind()


    task27 进阶:JS 核心之函数!!!重要_第12张图片
    image.png

    以后不准用f(1,2)这样调用函数,要用f.call(undefined,1,2)!!!!

this 和 arguments

function f(){
    'use strict'
    console.log(this)
    console.log(arguments)
    return undefined
}
f.call(1,2,3) // this 为 1,arguments 为 [2,3]

  1. call的第一个参数可以用this得到
  2. call的第一个参数后面的参数可以用arguments得到(arguments是一个伪数组
  3. 在普通模式下,如果this为undefined,那个浏览器会把this转换为window
  4. 在严格模式下('use strict'),传的是什么,this就是什么。this是call的第一个参数


    task27 进阶:JS 核心之函数!!!重要_第13张图片
    image.png
task27 进阶:JS 核心之函数!!!重要_第14张图片
严格模式.png

js中的new和this看起来没什么必要用,是有历史原因的,但是设计js的时候公司的要求是长得像java


task27 进阶:JS 核心之函数!!!重要_第15张图片
image.png
task27 进阶:JS 核心之函数!!!重要_第16张图片
伪数组.png

伪数组:长得像数组,但是原型链中没有Array.prototype。不可以使用push()、pop()这些数组的方法

什么是 call stack

stack:栈(先进后出)
调用栈:每进入一个函数,会把这个函数的位置记录到栈里面。等回来的时候直接就回到栈最上面的那个位置


task27 进阶:JS 核心之函数!!!重要_第17张图片
图片
  • 普通调用
  • 嵌套调用
  • 递归调用
function sum(n){
  console.log(n)
  if(n==1){
    console.log('return 1')
    return 1
  }else{
    console.log(`return ${n} + sum.call(undefined,${n-1})`)
    return n + sum.call(undefined, n-1)
  }
}
sum.call(undefined,5)
//sum(5)  //5+sum(4)
//sum(4)  //4+sum(3)
//sum(3)  //3+sum(2)
//sum(2)  //2+sum(1)
//sum(1)  //1
task27 进阶:JS 核心之函数!!!重要_第18张图片
image.png

可以打断点,在控制台看call stack↓


task27 进阶:JS 核心之函数!!!重要_第19张图片
image.png

但是这个栈是有上限的,太多的栈会爆掉的 stack overflow(栈溢出)


task27 进阶:JS 核心之函数!!!重要_第20张图片
image.png

作用域

  • 按照语法树,就近原则
  • 我们只能确定变量是哪个变量,但是不能确定变量的值


    task27 进阶:JS 核心之函数!!!重要_第21张图片
    语法树.png

    task27 进阶:JS 核心之函数!!!重要_第22张图片
    就近原则.png

    找当前作用域有没有这个变量的值,没有就向上一层找有没有,采取就近原则

//请分别说出每个位置的a是什么值?
var a = 1
function f1(){
  var a = 2
  f2.call()
  console.log(a)
  function f2(){
    var a = 3
    console.log(a)
  }
}
f1.call()
console.log(a)

题1

var a = 1
function f1(){
    alert(a) // 是多少
    var a = 2
}
f1.call()

拿到代码直接做——必然会错。请先提升声明!!!
变量提升!!!
等价于↓

var a = 1
function f1(){
    var a 
    alert(a) // 是多少
    a = 2
}
f1.call()

答案是:undefined

题2

var a = 1
function f1(){
    var a = 2
    f2.call()
}
function f2(){
    console.log(a) // 是多少
}
f1.call()

拿到代码直接做——必然会错。请先提升声明
答案是:1
题3

var liTags = document.querySelectorAll('li')
for(var i = 0; i

拿到代码直接做——必然会错。请先提升声明


task27 进阶:JS 核心之函数!!!重要_第23张图片
image.png

闭包

  1. 搜索:方应杭 闭包
  2. 看文章
//这个就是闭包
var a = 1
function f4(){
  console.log(a)
}
//如果一个函数,使用了它范围外的变量,那么(这个函数+这个变量)就叫做闭包

你可能感兴趣的:(task27 进阶:JS 核心之函数!!!重要)