函数笔记

函数定义

  • 匿名函数
    函数声明的时候 不要给名字 把它付给一个变量 作为函数的引用
    变量里面存的是 函数的地址
    函数是个对象 对象是存在堆内存里面 一般存它的地址
    它是匿名函数 但是它有name

  • 具名函数
    声明在顶级空间的话 作用域整个文件
    具名函数传给一个变量 作用域就是 具名函数部分
    超过这个部分 就访问不到它了
    函数后面加() 就代表 取它的返回值

function foo(){
  console.log(1)
}
var x = foo
var y = foo()
  • 箭头函数
  var fn6 = i => i+1
  var fn7 = (i,j) => i+j
  var fn8 = (i,j) => {console.log(i);return i+j}
//只有一句话 就不需要return了
//有两句话  就把return 现示 的 说出来

词法作用域

不会立即执行
抽象词法树 先看你语法对不对 再从头开始执行

  • 声明相关
 var global1 = 1
 function fn1(param1){
     var local1 = 'local1'
     var local2 = 'local2')
     function fn2(param2){
         var local2 = 'inner local2'
         console.log(local1)
         console.log(local2)
     }

     function fn3(){
         var local2 = 'fn3 local2'
         fn2(local2)
     }
 }

  • 示意图
    window
    global1 fn1
    param1(形参也算) local1 local2 fn2 fn3
    -------------------------------- local2 local2
    思路

首先 当前作用域 在fn2 里面找 local1 找不到
那么 找当前作用域上一层作用域 在fn2 同级里面找 local 找到了

fn3 里面的 local2 不会影响fn2 里面的 local2s
一个函数里面 能访问那些变量 在做词法分析的时候 就确定了
跟你调用不调用 没关系

注意的是 词法分析 只是 判断 这个变量 是不是 这个变量
不能判断它的值 是不是 这个变量的值 (因为 这个值可能会变)
分析语义 不分析值

call stack 栈

  • 先进后出

a 在执行之前先把它记下来
执行代码时 也把它的当前记下来
碰到函数 在执行之前 先把它的当前记下来
运行完了 就回到 刚才记下的地方
return 就离开函数 回到函数执行前 记下的位置
call stack 里 记录的是你是从哪儿离开的

  • 递归
    斐波拉契数列
    1 1 2 3 5 8 13...
    js是单线程的 所以它在执行一长串代码的时候
    他就会把当前的环境都记住
    我能访问那些变量 (this,arguments) 函数的地址
    突然它看到一个函数 这个时候 它就要切换环境 因为它要进入这个函数
    这个函数的 代码并不在这里 存在另一块内存
    那它进入这个函数之前 它有可能会忘掉怎么回来
    这个时候 它就在这里做个记号
    但是 它要做很多记号 也有可能 这个函数里面还有函数
    于是 它把每一层函数放到一个栈里面 这个栈就叫调用栈
    只要它进入一层调用栈 栈里面 就有多一个 关于它进入的时候的一个 记录
    于是 它就进入一个新的函数 开始执行了
    新的函数 如果还有函数呢 它就把第二个函数 又放到栈里面
    等它回来的时候 每次它就先回 最后进入的地方
    function fab(n) {
        if (n >= 3) {
            return fab(n - 1) + fab(n - 2);
        } else {
            return 1;
        }
    }
function foo(n) {

   function _foo(n, cur, total) {
      if (n <= 2) return total;
      return foo(n - 1, total, cur + total);
   }

   return _foo(n, 1, 1);
}//尾递归

call & apply & this & arguments

在你进入一个函数的时候 除了记录你进去的地址
还有你传给函数 的参数有哪些

  • this & arguments
    函数调用
    在函数调用时,要准备好 this
    如果没有this 就是 undefined 浏览器就转换成了window
    第二个 准备arguments 伪数组
    如果没有 arguments 就是空数组[]
function f(){
    console.log(this)
    console.log(arguments)
}
  • f.call()
    Window 就是 window
    f() 是阉割版的 f.call()
    this 就是 函数与对象之间的 羁绊

思路:

      var person = {
          name: 'frank',
          sayHi: function(person){
              console.log('Hi, I am' + person.name)
          },
          sayBye: function(person){
              console.log('Bye, I am' + person.name)
          },
          say: function(person, word){
              console.log(word + ', I am' + person.name)
          }
      }
      person.sayHi(person)
      person.sayBye(person)
      person.say(person, 'How are you')

      // 能不能变成 
      person.sayHi()
      person.sayBye()
      person.say('How are you')

person.sayHi()的时候
用this就能访问到 调用时候的person
可以这么写
既然你没有传person
那 我得找个 关键字来 代替 函数里面的person --> 用this关键字

person.sayHi()             //以 person 为this 调用sayHi
person.sayHi.call(person)  //以 person 为this 调用sayHi

      var person = {
          name: 'frank',
          sayHi: function(){
              console.log('Hi, I am' + this.name)
          },
          sayBye: function(){
              console.log('Bye, I am' + this.name)
          },
          say: function( word){
              console.log(word + ', I am' + this.name)
          }
      }

js之父 为了 满足 person.sayHi() 这样的代码能够运行
不用传person 我也能知道 当前对象是什么
于是 它创建了 this 这样的关键字
this是什么? 就是 函数之前的 .前面的东西
如果没.呢? this就是 window

var fn = person.sayHi

person.sayHi() //Hi ,I amfrank
fn() //Hi ,I am 
window.name = 'xxx' //Hi ,I amxxx

如果 我不想传 person 就给你传个对象 {name:‘xxx’}

person.sayHi.call({name:'xxx'}) //Hi ,I amxxx


function(){
              console.log('Hi, I am' + this.name)
          }

这个函数 是独立存在的
它和sayHi 、person 没有任何关系
就是和 call有关系
call 什么this 过来
函数里面的 this 就是什么

结论:

  • person.sayHi 等价于 person.sayHi.call(person)
  • fn() 等价于 fn.call()
  • call 的第一个参数 this
  • 如果你不想传 就传个 undefined 或者 null
  • 当你 没办法 把这个函数写完的时候
    你就直接把 参数的数组 传进去
    fn.apply(null,[1,2,3,4,5,6])
    当你不知道数组长度的时候 长度不固定 长度非常长的时候

fn.bind(this)

返回一个函数 这个函数 会把 bind 前面的函数 包起来
//函数 还没有执行

function(){
    fn.call()                   
}

call里面是什么?
bind里面是什么 它就是什么
bind的作用 就是在 调用fn时 在新fn的后面 加call

fn.bind = function(x,y,z){
    var oldFn = this //外面的fn  bind .前面的东西
    return function(){
        oldFn.call(x,y,z)
    }
}

旧函数调用bind 的时候会返回一个新函数
新的函数被调用的时候 会去调用旧函数
怎么调呢 在旧函数后面加个 call
call的第一个参数 就是bind 的第一个参数

如果你希望 一个函数里面和外面的 this一样的话 用箭头函数
因为箭头函数 本身是没有this的

箭头函数 对它来说 this永远没办法指定
它的this永远是它外面的this

function 本身是一定有this的

当进入一个function的时候
把它压到 call stack 里面
确定一个this 一定会确定this 没传也确定this

箭头函数呢
压到 call stack
不绑定this 绑定 arguments

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

推荐阅读更多精彩内容

  • 原文链接 Haskell和scala都支持函数的柯里化,JavaScript函数的柯里化还与JavaScript的...
    dreamapple阅读 2,507评论 0 24
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,515评论 0 5
  • 函数、对象 一. 目标 使用arguments获取函数的所有参数 arguments是一个伪数组,可以暂且作为一个...
    白小白不姓白阅读 212评论 0 1
  • 长久以来,面向对象在 JavaScript 编程范式中占据着主导地位。不过,最近人们对函数式编程的兴趣正在增长。函...
    神刀阅读 448评论 0 0
  • 天,灰蒙蒙的,像是死人的眼睛,没有一丝生气。 我,独自走在路上,步履缓慢,踟躇徘徊。 行至深巷,突然感觉身后一阵阴...
    小屁小屁阅读 233评论 0 0