美文网首页
JS 进阶 函数

JS 进阶 函数

作者: panw3i | 来源:发表于2018-07-22 20:08 被阅读7次

    函数的三种声明方式

    • 匿名函数

    • 具名函数

    • 箭头函数

    • 函数是JS的一等公民,具有相对独立内存空间

    • 函数本质上是对象,声明一个函数,会在栈空间保存函数的名称 , 指向实际堆空间内容

    • 三种声明的函数都有name属性

    词法作用域

    JS在运行代码前对代码做词法分析,其中参数,var变量,函数会进行声明前置,
    词法作用域仅在词法分析时有效,与后现赋值无关

    call stack

    每一次函数调用都会进入到新的函数开辟的空间中,并且在stack中记录当前的调用,开成调用栈,当函数调用完后,回退到调用的起点位置

    this

    fn = function(){
        console.log(this);
        console.log(arguments)
    }
    
    浏览器环境非严格模式下的this不传值的情况 函数对象的call方法

    由上可知:

    • this 是函数调用call的第一个参数
    • this 是一个对象
    • arguments 是除了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')
    
          // 那么源代码就要改了
          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)
              }
          }
          // 如果你不想吃语法糖
          person.sayHi.call(person)
          person.sayBye.call(person)
          person.say.call(person, 'How are you')
    
          // 还是回到那句话:this 是 call 的第一个参数
          // this 是参数,所以,只有在调用的时候才能确定
          person.sayHi.call({name:'haha'})  // 这时 sayHi 里面的 this 就不是 person 了
          // this 真的很不靠谱
    
          // 新手疑惑的两种写法
          var fn = person.sayHi
          person.sayHi() // this === person
          fn()  // this === window
    
    • 函数的调用本质上是相对独立的,函数只关心参数和返回值
    • 在进行普通调用时 person.sayHi() 其实是 person.sayHi.call(person) 的语法糖,函数内部的this 是 call 的第一个参数
    • fn() === window.fn.call(window),同样的语法糖 ,此时函数内部的this是 window
    • 不用this时,可以直接给call的第一个参数传 undefined

    call / apply

    • apply是call的另外一个版本
    • fn.call(asThis, p1,p2) 是函数的正常调用方式
    • 当你不确定参数的个数时,就使用 apply,参数为数组

    bind

    call 和 apply 是直接调用函数,而 bind 则是返回一个新函数(并没有调用原来的函数,高阶函数),这个新函数会 call 原来的函数,call 的参数由你指定。


    bind的内部实现原理

    柯里化 / 高阶函数

    柯里化 : 返回函数的函数

    高阶函数: 在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
    接受一个或多个函数作为输入:forEach sort map filter reduce
    输出一个函数:lodash.curry
    不过它也可以同时满足两个条件:Function.prototype.bind

    回调

    回调和同步和异步没有关系,仅表示函数作为参数传递给函数

    相关文章

      网友评论

          本文标题:JS 进阶 函数

          本文链接:https://www.haomeiwen.com/subject/woxrmftx.html