JavaScript函数以及js面试中常问的一些底层逻辑问题

1.for-in

1.1 对象类型(json数据)

  • 表现形式

    //1.对象(json数据) 
    var obj = {
        //属性  属性名:属性值  /    键值对 key:value
        z:1,
        name:"肖桂源",
        height:178,
        "age":23,
        "sex":"女",
        "weight":360,
        //方法
        "skill":function(){
            console.log("胸口碎大石");
        }
    }
    console.log(obj);
    console.log(obj.length);//undefined 对象是无序的没有长度的数据
    ​
    键值对存储key:value形式 ,name[键,key],"肖桂源"[值,value]
    注意:key可以不加引号,建议写的时候加上,避免在传输过程中被误认为变量
  • 获取对象的value(属性) 对象.key

    //1.获取数据  obj.key
    console.log(obj.name); //"肖桂源"
    console.log(obj.age); //23
    ​
    var w = "weight";
    console.log(obj.w); //undefined   .的后面就是属性,没有变量的概念
    console.log(obj[w]);//360 .后面接变量,使用[]代替点
    ​
    var h = "height";
    var oDiv = document.getElementsByTagName("div")[0];
    oDiv.style[h] = "300px";
    ​
    注意:点后面接变量、字符串,需用使用[]代替.,适用于所有这种场景
  • 写入键值对

    //2.设置数据    对象.属性名(key) = 属性值(value)
    obj.city = "北京";
    console.log(obj);

1.2 for-in

  • for-in:javascript中,专门用来循环(遍历)对象,因为(对象没有长度,无序)

  • 语法:for(var key in 遍历对象){ 循环体 }

    /*for-in:专门用于遍历对象,自动开始循环,到最后自动结束 
      语法:for(var 变量 in 遍历的对象){ 循环体 } */
    ​
    //1.遍历对象 (遍历:根据数据的规律,从头到尾执行一次,不允许中途结束
                // 循环:所有重复行为)
    for(var key in obj){
        console.log(key +"---------"+obj[key]); //.后面接变量用[]代替
    }

2.函数

  • 函数:函数就是将具有独立功能的代码块,整合到一起并命名,需要的时候调用即可(当它被调用时可重复使用代码块)

  • 作用:提高效率,提高代码重用率

2.1 函数的使用场景

  • 作为事件处理函数

  • 函数封装(代码复用)

  • 对象的方法

    //1.使用场景1:作为事件的处理函数
    document.onclick = function(){
        console.log("处理函数");
    }
    ​
    //2.使用场景2:封装(代码复用)
    function change(){
        oImg.src = "./img/"+n+".jpg";
        oPs[0].innerText = n + "/4";
        oPs[1].innerText = "动漫"+n;
    }
    ​
    //3.使用场景3:作为对象的方法
    var obj = {
        "name":"小芳",
        "skill":function(){
            console.log("敲代码");
        }
    }

2.2 函数声明

  • 普通函数声明方式

    • 声明:function 函数名(){ 代码块 }

    • 调用:函数名()

      say(); //可以声明前调用
      //1.声明:function 函数名(){  代码块  }
      function say(){
          console.log("你好啊,吃饭了吗?");
      }
      ​
      //2.调用 函数名()
      say();
      say();
      say(); //多次重复使用
  • 表达式函数声明方式

    • 声明:var 变量 = function (){ 代码块 }

    • 调用:变量名()

      fun(); //报错,只能先声明后调用
      //3.声明:var 变量 = function (){  代码块  }
      var fun = function(){
          console.log("我是一个表达式函数");
      }
      //4.调用:变量名()
      fun();
      fun();

2.3 函数参数

  • 什么时候使用参数:函数中出现不确定的值,就可以使用参数,传递不同参数实现不同效果

  • 参数

    • 形参:形式参数,function 函数名(a){ a---->形参

    • 实参:实际参数 函数名(10) 10---->实参

      //1.参数
      function sum(n){ //var n  ---- 形参
          var s = 0;
          for(var i = 1;i<=n;i++){
              s += i;
          }
          console.log(s);
      }
      sum(100); //100 实参   调用函数的时候会将100赋值给n
      sum(50);
  • 多个参数

    //2.多个参数,多个参数之间用逗号隔开,实参和形参之间一一对应赋值
    function add(a,b){
        console.log(a+b);
    }
    add(10,100); //a = 10;b = 100
  • arguments

    //3.如果参数个数确定不了的时候,不定义形参,使用arguments
    //声明一个函数,计算用户输入的所有值的和
    function jia(){
        //arguments函数内置对象,实参集合
        console.log(arguments); //Arguments(3)
        console.log(arguments.length); //获取集合的长度
        console.log(arguments[0]); //10
    
        var s = 0;
        for(var i = 0;i<arguments.length;i++){
            s += arguments[i];
        }
        console.log(s); 
    }
    jia(10,20,30);
    jia(10,20,30,40);
  • 参数类型

    所有js数据类型都能做完参数的参数,null和undefined一般不会作为参数传递,没有意义

    //1.字符串做参数  : 声明一个函数,通过id获取元素
    function getElement(id){
        var elem = document.getElementById(id);
        console.log(elem);
    }
    getElement("box"); //单词和字母不加引号就会认为是变量
    getElement("btn"); //单词和字母不加引号就会认为是变量
    
    
    //2.函数做为参数
    function two(){
        console.log("我是第二步操作");
    }
    
    function one(f){ //f = function two(){console.log("我是第二步操作");}
        console.log("我是第一步操作");
        f(); //调用f   --- >two
    }
    console.log(two); //function two(){console.log("我是第二步操作");}
    one(two);

2.4 作用域与预解析

2.4.1 作用域与作用域链

  • 作用域:指变量或函数的有效使用范围

  • 种类:全局作用域,局部作用域

    • 全局变量/函数:在函数外声明的变量/函数,就叫全局变量/函数,可以在页面的任何地方被访问和修改,会一直存储在内存中

    //1.全局变量/函数
    var a = 10;
    function fun1(){
        console.log(a); //10
        a = 20;
    }
    fun1();
    console.log(a); //20
    • 局部变量/函数:在函数内声明的变量/函数,就叫局部变量/函数,只能在函数内部使用,函数执行一结束,会被销毁

      //2.局部变量/函数
      function fun2(){
          var c = 10;
          console.log(c); //10
      }
      fun2();
      //console.log(c); //c is not defined  c是局部变量,只能在函数内部使用
      
      //只有函数内声明的才是局部变量,其他的{}无效
      if(1){
          var d = 666;
      }
      console.log(d);
  • 作用域链

    js中的一种查找机制,先找自己作用域范围内,依次往父级作用域查找,一直找到全局,全局还是找不到报错is not defind

    var x = 9;
    function outer(){
        //  var x = 99;
        function inner(){
            //  var x = 999
            console.log(x); //9
        }
        inner();
    }
    outer(); 

2.4.2 预解析

浏览器的js解析器在执行js的时候会进行很多操作,至少有两步

  • 1.预解析(变量提升):找东西

    • 找var,提前声明变量(只看=左的部分),只声明不赋值, 如果变量重名,只声明一次

    • 找function,提前声明整个函数,如果重名会多次声明,后面的会覆盖前面的

  • 2.逐行执行

  • 预解析找var

    //1.找var,提前声明变量(只看=左的部分),只声明不赋值, 如果变量重名,只声明一次
    console.log(a); //undefined
    var a = 10;
    console.log(a); //10
  • 预解析找function

    //2.找function,提前声明整个函数,如果重名会多次声明,后面的会覆盖前面的
    console.log(sum); //ƒ sum(){ console.log("函数2");}
    function sum() {
        console.log("函数1");
    }
    function sum() {
        console.log("函数2");
    }
  • 函数内部在代码执行之前也会进行预解析

    function fun1() {
        console.log(a); //undefined
        var a = 10;
        console.log(a); //10
    }
    fun1();
  • 面试题

    //面试题1.表达式函数和普通函数的区别
    //a1();  会提前声明整个函数,可以提前调用
    function a1() {
        console.log("我是一个表达式函数");
    }
    //a2()  会提前声明变量,undefined,不能提前调用
    var a2 = function () {
        console.log("我是一个表达式函数");
    }
    
    //面试题2, 代码执行后结果是?(预解析,重名覆盖,所有的声明都在预解析就已经完成)
    console.log(c); //整个函数 cccc2
    var c = 10;
    function c() {
        console.log("函数cccc1");
    }
    console.log(c);  //10
    var c = 20;
    function c() {
        console.log("函数cccc2");
    }
    console.log(c);  //20
    var c = 30;
    //c(); //c is not a function
    
    
    //面试题3:函数内部在代码执行之前也会进行预解析
    function fun1() {
        console.log(a); //undefined
        var a = 10;
        console.log(a); //10
    }
    fun1();
    
    //面试题4:预解析,作用域
    var x = 10;
    var y = 20;
    function fun2() {
        console.log(x, y); //undefined 20 
        var x = 10;
    }
    fun2();
    
    
    //面试题5: 预解析只声明=号左边的
    var m = 100;
    var n = 200;
    function fun3() {
        console.log(m, n); //undefined  200
        var m = n = 10;  //var m =      n =   
    }
    fun3();
    console.log(n); //10
    
    
    
    // 面试题6
    function fun4(z) { //函数执行第一步  传参
        console.log(z); //100
        var z = 10;
    }
    fun4(100);
    
    //面试题7
    function test(a, b) { 
    
        console.log(a); //function a(){}
    
        console.log(b); //undefined
    
        var b = 234; 
        console.log(b);  //234
    
        a = 123;
        console.log(a);  //123
        function a() { }
        var a;
        b = 234;
        var b = function () { };
        console.log(a);  //123
        console.log(b);  //function (){}
    }
    test(1)

2.5 函数返回值

  • 函数简单使用

    • return函数返回值:将函数内部的内容输出到函数外部,并且结束函数执行

    • 语法:return 值

      function sum(n) {
          var s = 0;
          for (var i = 1; i <= n; i++) {
              s += i;
          }
          //返回值
          return s;
      }
      var ss = sum(100);
      console.log(ss); //控制台打印5050
      
      var sss = sum(50);
      document.write(sss); //页面显示5050
      
      console.log(sum(70)); 
  • 特性

    • 一次只能返回一个

    • 函数中只要遇到return函数就会结束,一般情况下,return都会在函数的末尾

      //2.一次只能返回一个
      function fun(a, b) {
          var c1 = a + b;
          var c2 = a * b;
          //return c1,c2;  //40
          return { "add": c1, "c": c2 }
      }
      var s = fun(10, 4);
      console.log(s); //{add: 14, c: 40}
      
      
      //3.函数中只要遇到return函数就会结束
      function fun2(n) {
          var s = 0;
          for (var i = 1; i <= n; i++) {
              s += i; //0 + 1 = 1
              return s;//返回值,结束函数
          }
      }
      console.log(fun2(100)); //1

2.6 函数复用

代码复用:1.用循环不好写 2.结构一样,功能一致

执行步骤:

1.当他只有一个去实现,获取元素的时候必须通过父元素获取

2.将实现的代码放入函数中,将父元素作为参数传入

3.调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值