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


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
    
    
image.png

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'?
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属性

image.png

如何调用函数

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

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

image.png

image.png

image.png

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


image.png

image.png

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

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


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()


    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的第一个参数


    image.png
严格模式.png

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


image.png
伪数组.png

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

什么是 call stack

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


图片
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
image.png

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


image.png

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


image.png
image.png

stack overflow

作用域

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


    语法树.png

    就近原则.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<liTags.length; i++){
    liTags[i].onclick = function(){
        console.log(i) // 点击第3个 li 时,打印 2 还是打印 6?
    }
}

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


image.png

闭包

  1. 搜索:方应杭 闭包
  2. 看文章
//这个就是闭包
var a = 1
function f4(){
  console.log(a)
}
//如果一个函数,使用了它范围外的变量,那么(这个函数+这个变量)就叫做闭包
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容

  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 2,029评论 0 2
  • var navigator = navigator || {};var window = window || {}...
    DF_Sky阅读 1,248评论 0 0
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,788评论 0 38
  • 函数只定义一次,但可能被执行或调用任意次。JS函数是参数化的,函数的定义会包括一个称为形参的标识符列表,这些参数在...
    PySong阅读 524评论 0 0
  • 曾经的我特别害怕人,害怕成为众人焦点,害怕被讨论,害怕别人不喜欢我,害怕别人的评价不过是鼓励抑或欺骗。害怕与人交流...
    角落蜷缩阅读 268评论 0 0