js函数

作者: 阿龙哟 | 来源:发表于2018-10-14 12:30 被阅读0次
    function(输入1,输入2){
    //return undefined  你不写也会返回undefined 所以经常在开发者模式下写一个函数下面会有undefined返回值
    }
    

    console.log(x)
    打印什么和返回什么一点都不一样


    image.png

    JS的问题之一


    image.png
    image.png

    为什么上面定义function y(){} console.log(y) 就可以,下面var x = function y(){} console.log(y) 就会报错,显示y未定义 这个说明js不一致性,下面的y只在绿色区域内有效


    函数的5种声明方式

    1.function f(x,y){return x+y}
    
    2.f = function(x,y){return x+y}
    
    3.f = function x(){}
    
    4.f = new Function ('x','y','return x+y')
    
    5.f = (x,y) => x+y
    

    函数的name属性(毫无逻辑)

    function f(){}
    undefined
    f.name
    "f"//正常
    
    var f1 = function(){} 
    undefined
    f1.name
    "f1"//正常
    
    var f2 = function f3(){} 
    undefined
    f2.name
    "f3"//f3?what 之前不是说f3能用的地方很少。。
    
    var f4 = new Function('x','y','return x+y')
    undefined
    f4.name
    "anonymous"(匿名)// what?名字叫匿名。。。
    
    var f5 = (x,y) => x+y
    undefined
    f5.name
    "f5"// 正常
    

    函数的本质 调用:call

    函数是什么?

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

    创建函数内存图


    image.png
    用纯对象来实现函数
    var f = {} 定义一个对象
    f.name ='f' 对象name属性是'f'
    f.params=['x','y'] 对象的元素是'x','y'
    f.functionBody = 'console.log("fff")' 对象的函数体是 'console.log("fff")'
    f.call = function(){
      return window.eval(f.functionBody) 
    } 对象的call属性通过eval执行函数体
    f.call() 执行f.call  f和f.call()的区别 一个是对象,一个是执行函数
    

    什么是eval() 就是你给eval一堆字符串,他把字符串当成代码来执行


    世纪难题:f(1,2) <=> f.call(undefined,1,2) 两者是等价的,但是第二个才是真正的调用

    第一个是糖 第二个是硬核!!

    现在f 是函数 f.call()是函数调用


    this和arguments

    image.png

    1.call 的第一个参数可以用this得到
    2.call的后面的参数可以用arguments得到

    在普通模式下
    f=function(){console.log(this)}
    ƒ (){console.log(this)}
    f.call(undefined)
    Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
    call第一个参数传入undefined会打印出window(小写,浏览器抽风会显示成大写) 
    
    image.png
    在严格模式下
    f1 = function(){
    'use strict'
    console.log(this)
    }
    
    f1.call(undefined)
    VM204:3 undefined
    
    call 传入的第一个参数是什么,this就是什么,这里this就是undeifned
    
    image.png

    综上所述,this就是call传入的第一个参数

    arguments 是伪数组,怎么按断是不是一个伪数组
    就是看他的- - proto - -有没有指向Array.prototype
    或者说看他的原型链中有没有 Array.prototype


    函数的Call Stack 调用栈

    image.png

    普通调用

    普通调用.gif

    递归调用

    递归调用.gif

    嵌套调用

    嵌套调用.gif

    作用域
    函数当前的执行环境,作用域也可以被在层次结构中分层,以便子作用域可以访问父作用域,但反之不行。

    image.png

    传统错误:

    function f(){
      a=3
    }
    这里的a=3就是在声明全局变量,其实并不然
    
    

    首先这只是一个赋值表达式,当前作用域没有a这个变量,会沿着树也就是作用域链寻找,一直寻找到最外层window作用域中,仍然寻找不到,此时就会退而求其次,在window作用域中先声明变量a,然后再赋值a=3,所以a就成了全局变量

    经典面试题:

    面试题1
    var a = 1
    function f1(){
    alert(a) // 是多少 undefined
    var a = 2
    }
    f1.call()
    拿到代码直接做——必然会错。请先提升声明

    面试题2
    var a = 1
    function f1(){
    var a = 2
    f2.call()
    }
    function f2(){
    console.log(a) // 是多少1
    }
    f1.call()
    拿到代码直接做——必然会错。请先提升声明

    面试题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?6
    }
    }
    拿到代码直接做——必然会错。请先提升声明


    闭包

    如果一个函数,使用了他范围外的变量,那么(这个函数+这个变量)就叫做闭包

    相关文章

      网友评论

          本文标题:js函数

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