js常见面试笔试题

news2024/11/20 22:40:09

一.js实现距离最近的回文数

        给定一个整数 n ,你需要找到与它最近的回文数(不包括自身)。

        “最近的”定义为两个整数差的绝对值最小。

        示例 1:

                输入: "123"
                输出: "121"

function findNearestPalindromeNumber(num) {
let increment = 1;

// 判断是否为回文数
function isPalindrome(n) {[
let str = n.toString();
return str === str.split('').reverse().join("");

while (true) {
let nextlum = num + increment;
if (isPalindrome(nextNum)) (
return nextNum;
let prevNum = num - increment;
if (isPalindrome(prevNum)) [
return prewNum;
increment++;
console.log(findNearestPalindromeNumber(123)); //121 121console.log(findNearestPalindromeNumber(1234)): // 1221

二.数组扁平化

(将一个多维数组变为一个一维数组。例如,将数组[1, 2, [3, [4, 5]], [6, 7]]扁平化处理后输出[1, 2, 3, 4, 5, 6, 7];)

 function getArray(arr) {
        let res = [];
        for (let i = 0; i < arr.length; i++) {
            if (Array.isArray(arr[i])) {
                res = res.concat(getArray(arr[i]));
            } else {
                res.push(arr[i]);
            }
        }
        return res;
    }
    console.log(getArray([1, 2, [3, [4, 5]], [6, 7]]));//[1, 2, 3, 4, 5, 6, 7]

三.合并有序数组

给定两个从小到大排好序的数组,亲,请你把它两个合并成新的数组,合并后的结果依然有序。如:给定数组:[1,3,7,15,20]和数组:[-5,0,2,8,9,12]。那么结果是:[-5,0,1,2,3,7,8,9,12,15,20]

  function mergeSortedArrays(arr1, arr2) {
        var mergedArray = arr1.concat(arr2);
        return mergedArray.sort(function (a, b) {
            return a - b;
        });
    }
    var arr1 = [1, 3, 7, 11111,312323,313215, 20, 232132331];
    var arr2 = [-5, 0, 2, 8, 9, 12,111];
    var mergedArray = mergeSortedArrays(arr1, arr2);
    console.log(mergedArray); // [-5, 0, 1, 2, 3, 7, 8, 9, 12, 15, 20]
 
 let arr = [1, 2, 3]
    let arr1 = [3, 7, 5]
    let arr2 = [...arr, ...arr1]
    arr.sort((a, b) => a - b)
    console.log(arr2);

四.求两个数的交集

如:给定数组 [12,23,34,45]和数组 [21,23,45,100],那么交集是[23,34];

 function intersection(arr1, arr2) {
        var set1 = new Set(arr1);
        var set2 = new Set(arr2);
        var result = new Set();
        for (var value of set1) {
            if (set2.has(value)) {
                result.add(value);
            }
        }
        return Array.from(result);
    }
    var arr1 = [12, 23, 34, 45,21];
    var arr2 = [21, 23, 45, 100];
    var result = intersection(arr1, arr2);
    console.log(result); // [23, 45]

五.最接近三个数之和

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在恰好一个解。

function threeSumClosest(nums, target) {
        let closestSum = nums[0] + nums[1] + nums[2]; // 初始化最接近的三数之和
        for (let i = 0; i < nums.length - 2; i++) {
            for (let j = i + 1; j < nums.length - 1; j++) {
                for (let k = j + 1; k < nums.length; k++) {
                    const sum = nums[i] + nums[j] + nums[k];
                    if (Math.abs(sum - target) < Math.abs(closestSum - target)) { // 如果当前的三数之和更接近目标值,则更新最接近的三数之和
                        closestSum = sum;
                    }
                }
            }
        }
        return closestSum;
    }
    console.log(threeSumClosest([1, 2, 3, 4, 5], 7)) 

六.实现事件处理器EventEmitter,有如下功能   

        const event = new EventEmitter(); 

        绑定事件

        event.on(name, callback);

        取消绑定

        event.off(name);

        触发事件

        event.emit(name, data);

 // 自己实现一个事件处理机制:(事件绑定,事件触发,事件解绑);
    class EventEmitter {
        constructor() {
            this.events = {};
        }
        // 绑定事件:
        // 参数:
        //    name:事件名
        //    callback:事件处理函数
        on(name, callback) {
            this.events[name] = callback;
        }
        // 触发事件
        //   name:事件名
        //   data:传给事件处理函数的参数
        emit(name, data) {
            this.events[name](data);
        }
        // 解绑事件:
        // 参数:
        //   name:事件名
        off(name) {
            delete this.events[name];
        }
    }
    const event = new EventEmitter();
    // 绑定事件
    event.on("myclick", function (params) {
        console.log("myclick", params);
    });
    event.on("yourclick", function (params) {
        console.log("yourclick", params);
    });
    function fn01() {
        // 触发事件
        event.emit("myclick", "hi");
    }
    function fn02() {
        event.emit("yourclick", "hello");
    }
    function fn03() {
        // 取消绑定
        event.off("myclick");
    }

七.请阅读如下代码(非严格模式下),写出结果,并写出为什么? 

  var a = 2;
    const foo = {
        bar: function () {
            console.log(this.a,"20");
        },
        bar1: function () {
            return function () {
                console.log(this.a,"24");
            }
        },
        a: 1
    }; 
    foo.bar();//1
    var bar1 = foo.bar1();
    console.log(bar1,"31")
    bar1();//2  
    // foo.bar() 方法是直接通过 foo 对象调用的,所以其中的 this 指向的是 foo 对象本身,而 foo 对象中的 a 属性的值为 1,所以输出结果为 1。
    // 而执行 bar1() 方法时,实际上是通过 return 返回的函数执行的,因此其执行上下文中的 this 指向的是全局对象 window(或者在某些环境中是 global 对象),而全局对象中定义的 a 变量的值为 2,所以输出结果为 2。

八.请编写函数,将data数组中所有对象按照value从小到大排列,不能使用sort函数。

      var data = [{
             name: "uc",
             value: 5
         }, {
             name: "amap",
             value: 2
 
         }, {
             name: "ali",
             value: 3
         }
       ]
function bubbleSort(arr, compareFn) {
        for (var i = 0; i < arr.length; i++) {
            for (var j = 0; j < arr.length - 1 - i; j++) {
                if (compareFn(arr[j], arr[j + 1]) > 0) {
                    [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
                }
            }
        }
        return arr;
    }
    function compareByValue(a, b) {
        return a.value - b.value;
    }
    console.log(bubbleSort(data, compareByValue))

九.封装一个queryString函数,支持输入 URL来获取 query 等参数)

例如,输入https://www.antgroup.com?
name=ant&from=alibaba&job-frontend&extraInfo %7B%22a%22%3A%226%22%2C%22C%22%3A%22d%22%7D
可得到一个这样的对象
(name:"ant",from: "alibaba' ,job: "frontend" ,extraInfo: (a:"b', c:'d]}  

  function getURLParams(url) {
        const [fullURL, queryString] = url.split('?'); // 将 URL 分割成 URL 本身和查询字符串两部分
        const query = new URLSearchParams(queryString); // 使用 URLSearchParams 解析查询字符串
        const result = {}; // 初始化结果对象
        for (const [key, value] of query) { // 遍历解析后的查询字符串
            if (/\[\]$/.test(key)) { // 如果键以 [] 结尾,说明这是一个数组
                const name = key.slice(0, -2); // 去掉 [] 后缀,得到数组名
                if (result[name]) { // 如果结果对象已经有了这个数组
                    result[name].push(parseParamValue(value)); // 在数组中添加新的值
                } else {
                    result[name] = [parseParamValue(value)]; // 否则创建一个新的数组
                }
            } else { // 否则这是一个普通的键值对
                result[key] = parseParamValue(value); // 直接将值添加到结果对象中
            }
        }
        // return { url: fullURL, query: result }; // 返回 URL 和解析后的查询参数对象
        return result
    }
    function parseParamValue(value) { // 解析参数的值
        try { // 尝试解析 JSON
            return JSON.parse(value);
        } catch { // 如果失败则返回原始字符串
            return value;
        }
    }
    const url =
        "https://example.com/path?param1=value1&param2=[1,2,3]&param3=%7B%22key%22%3A%22value%22%7D&param4=not%20a%20JSON";
    const params = getURLParams(url); // 获取解析后的查询参数对象
    console.log(params); // 输出查询参数对象

十.用递归实现:求两个数的最大公约数(思路:使用欧几里得算法)。要求封装成函数。

    //     首先确定如何求最大公约数,我们采用欧几里得算法(辗转相除法),算法描述如下:
    //     例:48, 57
    //     57 % 48=9     大数对小数求余
    //     48 % 9=3       小数对上次的余数求余,重复这个过程直到余数为0
    //     9 % 3=0	        余数为0时,此次求余的小数就是最大公约数
    //     第一次运算n1 = 57, n2 = 48, n3 = 9,第二次运算n1 = 48, n2 = 9, n3 = 3, 第三次运 
    //     算n1 = 9, n2 = 3, n3 = 0
    //     规律是:求余的大数是前次运算的小数,小数是前次运算的余数,余数是0就结束。
    function gongYS(n1, n2) {
        let n3 = n1 % n2;
        n1 = n2;
        n2 = n3;
        if (n3 == 0) {
            return n1;
        }
        return gongYS(n1, n2);
    }
    console.log(gongYS(48, 57));
====================================================================================
    // //利用递归求两个数的最大公约数
    // function gongYS(m, n) {//最大公约数函数
    //     var r = 0;//声明变量r;
    //     r = m % n;//把m%n的值赋值给r;
    //     m = n;//把n的值给m;
    //     n = r;//把r的值给n;
    //     if (r == 0) {//如果r等于0,说明最大公约数是那个值小的数,比如:16/8;
    //         return m;//n的值赋值给m后,返回值为m;
    //     }
    //     return gongYS(m, n);//否则继续运行函数
    // }
    // var result = gongYS(16, 24);
    // console.log(result);

十一.请把下面的对象数组变成对象嵌套。 

            规则:每个对象的parentId就是父级对象的id。 

  // let arr = [
    //     {
    //         id: 1,
    //         name: "张一",
    //         parentId: null
 
    //     },
    //     {
    //         id: 2,
    //         name: "张二",
    //         parentId: 1
    //     },
    //     {
    //         id: 3,
    //         name: "张三",
    //         parentId: 1
    //     },
    //     {
    //         id: 4,
    //         name: "张四",
    //         parentId: 2
    //     },
    //     {
    //         id: 5,
    //         name: "张五",
    //         parentId: 2
    //     },
    //     {
    //         id: 6,
    //         name: "张六",
    //         parentId: 3
    //     },
    //     {
    //         id: 7,
    //         name: "张七",
    //         parentId: 4
    //     },
    //     {
    //         id: 8,
    //         name: "张八",
    //         parentId: 6
    //     }
    // ]
    //方法一:======================================================================
 function arrToJson(root) {
        // 2、循环数组,找子元素
        let children = arr.filter(item => item.parentId == root.id);
 
        if (children.length > 0) {
            root.children = children;
            children.forEach(item => {
                arrToJson(item);
            })
        };
    }
    // 1、先找的根元素;
    let root = arr.filter(item => item.parentId == null)[0]
    arrToJson(root);
    console.log(root);
    //方法二:======================================================================
 function arrToJSON(arr) {
        let root;
        arr.forEach(item => {        
            if(item.parentId!=null){
                // 如果有父级
                // 找到父级
                let parentObj = arr.filter(parentItem=>parentItem.id===item.parentId)[0];
                // 给父级增加children属性(数组)
                !parentObj.children && (parentObj.children=[]);
                // 把自己添加到父级的children属性(数组)
                parentObj.children.push(item);
 
            }else{
                root = item;
            }
        });
        return root;
    }
    console.log(arrToJSON(arr));
    console.log(arr.length);

十二.封装一个函数,完成功能:add(2).multi(9).div(3) 的结果是6。 

function add(x) {
  return {
    multi(y) {
      return {
        div(z) {
          return x*y/z;
        }
      }
    }
  };
}
console.log(add(2).multi(9).div(3)); // 输出6
console.log(['1', '2', '3'].map(parseInt))

十三.['1', '2', '3'].map(parseInt)的结果是什么 ? 为什么 ? 

 console.log(['1', '2', '3'].map(parseInt));//[1, NaN, NaN];
    // 这是因为 map 函数会将数组中的每一个元素都调用一遍指定的函数,
    // 并将函数的返回值组成一个新的数组返回。parseInt 函数的第二个参数表示进制,
    // map 函数会将当前元素的值和索引分别作为 parseInt 函数的第一个和第二个参数传入。
    parseInt('1', 0); // 1
    parseInt('2', 1); // NaN,因为 '2' 不是一进制的数
    parseInt('3', 2); // NaN,因为 '3' 不是二进制的数

十四.请用两种方式完成数组去重

方式一
    function norepeat(arr){
      var newarr = [];
      for(var i = 0;i<arr.length;i++){
          if(newarr.indexof(arr[i]) == -1){
             newarr.push(arr[i])
          }
      }
      return newarr;
}
方式二
     function norepeat(arr){
       var newarr = arr; 
       var obj = {};
       for(var i = 0;i<arr.length;i++){
          obj[arr[i]] = 1;
       }
       return Object.keys(obj).map(item=>Number(item));
     }
方式三
     function norepeat(arr){
      var newarr = arr;
       newarr.sort();
       for(var i = 0;i<newarr.length;i++){
          if(arr[i] == arr[i+1]){
             arr.splice(i,1)
             i--;
          }
       }
       return newarr;
     }
方式四
     function norepeat(arr){
        return Array.from(new Set(arr));
     }

十五.请写出常见的http状态码与含义(4种以上)

200:(成功)服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。

400:(错误请求)服务器不理解请求的语法

401:(未授权)请求要求身份验证。对于需要登录的网页,服务器可能返回此响应

403:(禁止)服务器拒绝请求

404:(未找到)服务器找不到请求的网页

408:(请求超时)服务器等候请求时发生超时

500:(服务器内部错误)服务器遇到错误,无法完成请求

502:(错误网关)服务器作为网关或代理,从上游服务器收到无效响应

503:(服务不可用)服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态

504:(网关超时)服务器作为网关或代理,但是没有及时从上游服务器收到请求

505:(HTTP 版本不受支持)服务器不支持请求中所用的 HTTP 协议版本

十六. 如何解决跨域 并说出ajax与解决跨域方式的区别

        ①解决跨域三种方案:jsonp、cors、proxy
        ② AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。(注意!ajax不是跨域方式!它是一种技术)
请问jsonp是不是ajax中实现跨域访问的技术

        ​ jsonp不是AJAX中实现跨域访问的技术 ​

        1、jsonp没有使用XMLHttpRequest对象。 ​

        2、jsonp只是在一种跨域的技巧。 ​

        3、jsonp只支持Get方式;由于按照jsonp的这种方式跨域访问时,就是可以利用javascript和服务器端交互,能达到AJAX中XMLHttpRequest对象同样的效果

十七.Js垃圾回收机制是什么请简述

        ①概念
        js的垃圾回收机制是为了防止内存泄漏(已经不需要的某一块内存还一直存在着),垃圾回收机制就是不停歇的寻找这些不再使用的变量,并且释放掉它所指向的内存。
在JS中,JS的执行环境会负责管理代码执行过程中使用的内存。

        ②变量的生命周期
        当一个变量的生命周期结束之后,它所指向的内存就会被释放。js有两种变量,局部变量和全局变量,局部变量是在他当前的函数中产生作用,当该函数结束之后,该变量内存会被释放,全局变量的话会一直存在,直到浏览器关闭为止

        ③js垃圾回收方式有两种方式: 标记清除、引用计数
        标记清除:
        大部分浏览器使用这种垃圾回收,当变量进入执行环境(声明变量)的时候,垃圾回收器将该变量进行了标记,当该变量离开环境的时候,将其再度标记,随之进行删除。
        引用计数:
        这种方式常常会引起内存的泄露,主要存在于低版本的浏览器。它的机制就是跟踪某一个值得引用次数,当声明一个变量并且将一个引用类型赋值给变量得时候引用次数加1,当这个变量指向其他一个时引用次数减1,当为0时出发回收机制进行回收

        ④垃圾回收机制优化 

        增量CG、分代回收 

十八.请说出你对this的理解

        this是es6新增的函数内置对象,this是代名词。this代表谁,需要看场景(上下文),在js中函数就是this的场景。所以,this一般都是出现在函数内部(其实这个本质是作用域)。

        this的几种情况(静态的描述)//以下情况所说的函数是非箭头函数。

        1)、当this所在函数是事件处理函数时,this表示事件源。

        2)、当this所在函数是构造函数时,this表示new出来的对象。

        3)、当this所在函数是实例(对象)的方法时,this表示调用该方法的对象。

        4)、当this所在函数是全局声明的函数时,

                4.1)、非严格模式下:this表示window。(其实这个点和第三点一样)。因为,全局函数都是window对象的方法

                4.2)、严格模式下:this是undefined。

        5)、this在script标签里,表示window。

        箭头函数是没有this的。

                既就是:在判断this指向时,不要把箭头函数当函数看待。

                箭头函数在编译的原理里是词法分析域     

十九.解释一下什么是 promise ?包含状态与方法

        ①Promise的概念
            Promise是ES6提供的原生的类(构造函数), 用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作)

        ②Promise的两个特点
            1.对象的状态不受外界影响
        Promise 有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和                    Rejected(已失败)

            2.一旦状态改变,就不会再变
        状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected

        ③Promise的作用:解决回调地狱的问题
        ④Promise类的方法:

1. 对象方法:then,catch
then方法:
功能:把then方法的参数传给resolve和reject。 promise对象.then(resolve回调函数,reject回调函数);
参数:then方法的第一个参数是resolvethen方法的第二个参数是reject。
返回值:promise对象本身,所以,then调用完毕后,还可以继续调用then(即:链式调用)
Promise中then方法的数据传递
上一个then的返回值(结果)是下一个then的参数(输入)

catch方法:
它和then的第二个参数一样,用来指定reject的回调

2.类方法:all、race

all方法:
功能: Promise.all可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据。返回的数据与传的参数数组的顺序是一样的。当所有的异步操作都成功才表示成功 。
参数:数组。数组里是若干个返回promise对象的函数(异步操作);
返回值:promise对象。promise对象的then方法的回调函数的参数是 所有promise对象的resolve的参数(数组形式)
用Promise.all来执行,all接收一个数组参数,两个异步操作是并行执行的,等到它们都执行完后才会进到then里面。而两个异步操作返回的数据都在then里面,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results

race方法:
功能:也是并发,但是,与all不同之处时,当一个异步操作完成(resolve或reject)时,就调用方法了。即:多个异步操作,同时执行,谁快就用谁的结果,所以,结果不再是数组。

        ⑤总结Promise的使用步骤
        1、找到(曾经的)异步操作的代码,放在Prmoise构造函数的参数(函数)里

         2、参数(函数)的第一个参数resolve是成功时调用的函数,对应then方法(函数)的第一个参数

        3、参数(函数)的第二个参数reject是失败时调用的函数,对应then方法(函数)的第二个参数

二十 .解释一下JS的展开操作符?什么是解构?

        展开操作符...作用就是展开数组或字符串为一个新数组。

        解构就是按照一定的模式或者规则,在数组和对象中提取值,并且对变量进行赋值的操作。优点:简洁易读,语义清晰明了,也方便在复杂数据中对数据字段的获取。

二十一.根据一个数字日期,判断这个日期是这一年的第几天例如: 2016和02和11,计算后结果为42

   var date = prompt("请输入数字日期:")
    date = Number(date)
    var year = parseInt(date / 10000)
    var month = parseInt((date - year * 10000) / 100)
    var day = parseInt(date - year * 10000 - month * 100)
    var num = 0
    switch (month) {
        case 12: num += 30
        case 11: num += 31
        case 10: num += 30
        case 9: num += 31
        case 8: num += 31
        case 7: num += 30
        case 6: num += 31
        case 5: num += 30
        case 4: num += 31
        case 3: num += 31
            if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0) {
                num += 29
            } else (
                num += 28
            )
        case 2: num += 31
        case 1: num += day
            break;
        default: alert("输入错误")
    }
    document.write(num);

二十二.红灯三秒亮一次,绿灯一秒亮一次,黄灯2秒亮一次;如何让三个灯不断交替重复亮灯?(用Promse实现)三个亮灯函数已经存在 提示可以使用递归来实现

 function getLight(name, num, color) {
        document.getElementsByClassName(name).style.backgroundColor = color;
        document.getElementsByClassName(name).innerHTML = num;
        return new Promise(function (resolve, reject) {
            let myTimer = setInterval(function (params) {
                num--;
                if (num <= 0) {
                    num = 0;
                    clearInterval(myTimer);
                    myTimer = undefined;
                    document.getElementsByClassName(name).style.backgroundColor = "white";
                    resolve();
                }
                document.getElementsByClassName(name).innerHTML = num;
            }, 1000)
        })
    }
    function shanshan() {
        getLight(red, 5, red).then(function () {
            return getLight(green, 5, green)
        }).then(function () {
            return getLight(yellow, 5, yellow)
        }).then(shanshan);
    };
    shanshan();

二十三.以下代码最后输出什么?(考察eventloop)

const first = () => (new Promise((resolve, reject) => {
        console.log(3);//同步代码
        let p = new Promise((resolve, reject) => {
            console.log(7);//同步代码
            setTimeout(() => {
                console.log(5);//宏任务
                resolve(6);
            }, 0)
            resolve(1);
        });
        resolve(2);
        p.then((arg) => {
            console.log(arg);
        });
    }));
    first().then((arg) => {
        console.log(arg);
    });
    console.log(4);//同步代码
// 输出结果为3,7,4,1,2,5

二十四.封装一个函数实现判断100以内的素数

 // 求1-100的素数 
 function getSuNum(num) {
        let str = '';
        for (let i = 2; i < num; i++) {
            for (let j = 2; j < i; j++) {
                if (i % j === 0) {
                    break;
                } else if (i === j) {
                    str += i + " "
                }
            }
            return str;
        }
        console.log(getSuNum(100));
    }

二十五.封装一个函数计算给定数组 arr 中所有元素的总和 (数组中的元素均为 Number 类型)

    function getAddNum(arr) {
        let sum = 0;
        for (let i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }
    console.log(getAddNum([1, 2, 3, 4]));

二十六.如何判断数据的类型是否是数组类型?有哪些方法?

instanceof 运算符 , 主要是判断某个实例(arr)是否属于某个对象

  

constructor 判断实例(arr)的构造函数是否等于某个对象

  

isArray 判断是不是数组

Object.prototype.toString.call() 把对象转为字符串和一个已知的对象进行对比

二十七.数组的方法都有哪些(至少12个), 哪些方法可以改变原数组?

  改变原始数组:
        ①arr.push(元素1,元素2...)尾加

            返回值:追加数据之后数组的最新长度 参数:一个或者多个元素

        ②arr.pop()尾删  返回值:被删除的数据  参数:无

        ③arr.unshift(元素1,元素2...)头增  返回值:追加数据之后数组的最新长度

        ④arr.shift()头删  返回值:被删除的数据

        ⑤arr.reverse()反转数据  返回值:反转之后的数组

        ⑥arr.sort()排序返回值:排序后的数据

            arr.sort(function(a,b){return a-b})a-b就是从小到大

            arr.sort(function(a,b){return b-a})b-a就是从大到小

        ⑦arr.splice(索引)开始索引删除到最后   返回值:以数组形式返回删除的元素

           arr.splice(索引,长度n)从索引开始删除到n个  返回值:以数组形式返回删除的元素

           arr.splice(开始索引,长度n,元素1,元素2...)从索引开始删除到n个后,在删除的位置增加元       素1,元素2  返回值:截取出来的新数数组

  不改变原始数组
        ⑧arr.concat(元素1,元素2...)数组的拼接

                返回值:拼接好的新数组  参数:一个或者多个数组

        ⑨arr.join(‘连接符’)将数组中的数据连接成一个字符串。

                返回值:空字符串或者连接好的字符串

        ⑩arr.slice(开始索引,结束索引) 截取数组内的数据  返回值:截取出来的新数组

            (包前不包后,可写负数)

        ①①arr.indexOf(数据)从左到右找该数据第一次出现的位置、索引,找不到该数据就返回-1

               arr.indexOf(数据,开始索引)从开始索引位置后找该数据第一次出现的位置

                返回值:数据对应的索引,找不到该数据就返回-1

        ①②lastIndexOf()和indexOf一样,只不过是从后向前找

二十八.简述call,appy,bind三个方法?

 ①call和apply:   

     1、call和apply都是函数的一个方法(函数),

     2、call和apply都是在调用原函数。

     3、call和apply是可以改变原函数里的this指向的。

     4、call和apply的第一个参数就是原函数的this指向。

     5、call可以把函数和对象解耦(耦合度:依赖程度/关联程度。高内聚,低耦合)

     6、call和apply的区别(仅仅只是格式上的区别): 1)、call函数从第二个参数朝后的参数是原函数的参数 2)、apply函数只有两个参数,第二个参数是个数组,数组里是原函数的参数。这样的话,apply第二个参数就可以使用arguments。

 ②bind和call、apply的区别:      

        相同点:  bind,call,apply都可以改变this的指向。 

        不同点:1、bind不会调用原函数,而会产生一个新的函数(bind的返回值是新函数),新函数里的this是bind时的对象。bind有强烈绑定的意思。只要调用bind,那么对象和函数就永远绑定起来了。 2、call和apply会调用原函数      

二十九.http和https有什么区别?        

        ①https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

        ②http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

        ③http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

        ④http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全

三十 .Get和post有什么区别?

        ①相同点:

        get和post就是客户端给服务器传输数据(携带的参数)的方式。

        ②不同点:

        get: 速度快,传输的数据量小,安全性不好,get的数据在请求行发送的(请求行的地址发送到)

        post:速度慢,传输的数据量大,安全性好,post的数据在请求体发送的

三十一.请说一说你对eventloop的理解? 

        浏览器的事件循环分为同步任务和异步任务;所有同步任务都在主线程上执行,形成一个函数调用栈(执行栈),而异步则先放到任务队列里,任务队列又分为宏任务与微任务。下面的整个执行过程就是事件循环 

三十二.请写出Ajax请求的核心步骤?

    function getData() {
        // 1、创建XMLHttpRequest。
        let xhr = new XMLHttpRequest();
        // 2、设置请求的地址,请求方式,是否异步(默认是异步)
        xhr.open("get", "http://118.178.238.19:3001/api/banner/list");
        // 3、设置:当后端响应回来后,需要干什么
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                // 5、获取后端响应回来的数据:xhr.responseText
                console.log("xhr.responseText", xhr.responseText);
            }
        }
        // 4、发送请求
        xhr.send();
    }

三十三.求斐波那契数列的第n项的值, 要求能算出第50项, 第100项的值 

   function Fibonacci(n) {
        var n1 = 1;//储存f-2
        var n2 = 1;//储存f-1
        var n3 = 0;//储存取得值
        //i=2,因为第一个算的就是第三个的值
        for (var i = 2; i < n; i++) {
            n3 = n1 + n2;
            //为取下一个值做准备,原来的n-1变成n-2,当前取出的值变成了下一个的n-1
            n1 = n2;
            n2 = n3;
        }
        return n3;
    }
    console.log(Fibonacci(50));

三十四.实现数组/对象的深拷贝 

// 实现对象深拷贝:for循环 + 递归=========================================================
 function copyObj(obj) {
    var newobj = {};
    for (var key in obj) {
      if (typeof obj[key] == 'object') {
        newobj[key] = copyObj(obj[key]);//发现 obj的键对应的值是复杂数据类型,让复杂数据类型在进行函数的调用
      } else {
        newobj[key] = obj[key];// 向newobj添加键值对,键是key,值是key对应的值
      }
    }
    return newobj;
  }
  var obj = { name: "zs", wife: { name: "zs的妻子" } }
  var newobj = copyObj(obj);
  console.log(obj);//{name: 'zs', wife: {…}}
  console.log(newobj);//{name: 'zs', wife: {…}}
  obj.wife.name = 'ls的妻子'
  console.log(obj.wife.name);//ls的妻子
  console.log(newobj.wife.name);//zs的妻子
// 实现数组深拷贝:JSON.parse(JSON.stringify())===========================================
  var arr = [12, [12, 34, 56, 67], [12, 34, 65]];
  var newarr = JSON.parse(JSON.stringify(arr))
  console.log(newarr);
  //  第一层相互受影响吗? 不影响
  arr[0] = 10
  console.log(arr[0]); // 10
  console.log(newarr[0]); // 12
  // 第二层相互受影响吗? 不影响
  arr[1][0] = '新'
  console.log(arr[1][0]); // "新"
  console.log(newarr[1][0]); // 12
 
  // 封装一个函数,既能实现数组的拷贝,也能实现对象的拷贝==================================
    function copyEle(ele) {
        if (ele instanceof Array) { // 如果ele是数组的类型
            var newarr = [];//创建一个新的空间
            for (var i = 0; i < arr.length; i++) {
                if (typeof (arr[i]) == 'Object') {
                    newarr.push(copyArr(arr[i]))
                } else {
                    newarr.push(arr[i])
                }
            }
            return newarr;
        } else if (ele instanceof Object) { // 判断传入的是不是对象类型
            var newobj = {};
            for (var key in obj) {
                if (typeof obj[key] == 'object') {
                    newobj[key] = copyObj(obj[key]);//发现 obj的键对应的值是复杂数据类型,让复杂数据类型在进行函数的调用
                } else {
                    newobj[key] = obj[key];// 向newobj添加键值对,键是key,值是key对应的值
                }
            }
            return newobj;
        }else{
            return "请传入数组或者对象类型"
        }
    }

三十五.实现字符串的反转( 不能使用split和reverse方法 )

   function reverseString(str) {
        var newStr = "";
        for (var i = str.length - 1; i >= 0; i--) {
            newStr += str[i];
        }
        return newStr;
    }
    console.log(reverseString('hello'));

三十六.对象转为查询字符串格式

 function getObj(obj) {
        var str = '';
        for (var k in obj) {
            str += `${k}=${obj[k]}&`
            str = str.slice(0, -1)
        }
        return str;
    }
    let newobj = {
        name: "zs",
        sex: "男",
        age: 18
    }
    console.log(getObj(newobj));//name=zssex=男age=18
========================================================================================
   let obj = {
        name: "capper",
        age: 18,
        sex: "男"
    }
    let url = "https://www.antgroup.com?"
    function getStr(url, obj) {
        let str = "";
        for (let key in obj) {
            str += `${key}=${obj[key]}&`
        }
        str = `${url}${str}`
        return str;
    }
    console.log(getStr(url, obj));

三十七. 查找字符串数组中的最长公共前缀(如果不存在公共前缀,返回空字符串 "")

        输入:["flower","flow","flight"]

        输出:"fl"

function publicPrefix(arr) {
        let i = 0;//字符串的下标。
        while (true) {
            let char = arr[0][i];//数组第一个元素的第i个字符
            // j是数组的下标
            for (let j = 1; j < arr.length; j++) {
                if (char != arr[j][i]) {
                    return arr[0].substring(0, i);
                }
            }
            i++;
            if (i > arr[0].length - 1) {
                return arr[0];
            }
        }
    }
    console.log(publicPrefix(["flower", "flow", "flight"]));//fl

三十八.请阅读如下代码(非严格模式下),写出结果,并写出为什么? 

  const promise1 = new Promise((resolve, reject) => {
        console.log('promise1');//同步
        resolve();
    })
    promise1.then(() => {
        console.log(3);//微任务
    })
    console.log(1);//同步
    const fn = () => new Promise((resolve, reject) => {
        console.log(2);//同步
        resolve('success')
    })
    fn().then((res) => {
        console.log(res)//微任务
    })
    console.log('start');//同步
 
// 输出结果为:promise1,1,2,start,3,success

三十九.原型原型链        

  1. : 1-1 作用:共享方法。挂载到原型对象上的方法可以被所有实例对象共享 1-2 3个特性:

    • 每一个构造函数都会有一个原型对象prototype,也叫显式原型,挂载到原型对象上的方法可以被所有实例对象共享

    • 每一个实例对象,都会有一个隐式原型__proto__,也叫隐式原型,现在浏览器常写作[[prototype]],隐式原型会指向构造函数的原型对象,隐式原型在实际开发中不会使用,只会指向构造函数的原型对象

    • 每一个原型对象都会有一个构造器constructor,他会指回构造函数本身 (Person.prototype.constructor==Person)

  2. 原型链: 1-1 作用:规定对象属性和方法的查找规则。 首先在实例对象上查找,找到使用,没有找到,就去构造函数的原型对象上查找,找到使用,没有找到,就去object的原型对象上都没有找到,就会报错 1-2 3个特性:

    • 原型对象也是对象,也有隐式原型__proto__,原型对象的隐式原型指向Object的原型对象

    • Object的原型对象也是对象,有隐式原型__proto__,他的隐式原型指向null

    • Object的原型对象也会有一个构造器constructor,他会指回Object构造函数本身

四十.闭包是什么?有什么特性?对页面会有什么影响?

  1. 概念:

  • 1.只要跨作用域访问了变量,这种现象就是闭包

  • 2.父函数内部访问其他作用域标识符的子函数

  1. 语法:1.立即执行函数把值接出去2.将函数挂载到window上 闭包标准写法: 1.在父函数内部定义一个变量 2.在子函数内部访问该变量 3.将这个子函数return出去或者挂载到window对象上的任意属性上

  2. 作用(好处):

  • 1.可以支持跨作用域访问变量,延伸变量的作用范围

  • 2.保证闭包内部私有变量的安全性,避免全局变量因为命名冲突造成的污染

  • 3.早期的模块化的实现方案

  1. 缺点:

  • 1.闭包始终会有使用一个全局标识符用来接收子函数,会造成内存浪费 ,在ie低版本浏览器下,甚至会造成内存泄露

  • 2.原本函数执行完毕,其内部的标识符就会销毁,但是因为和外部的全局标识符有引用关系,就不能得到及时销毁,会造成内存的浪费

 

       

               

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/591045.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jenkins+Python自动化测试之持续集成详细教程

前言 今天呢笔者想和大家来聊聊JenkinsPython自动化测试持续集成&#xff0c;废话呢就不多说了哟咱们直接进入主题哟。 一、Jenkins安装 ​ Jenkins是一个开源的软件项目&#xff0c;是基于java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供…

I.MX RT1170加密启动详解(2):Authenticated HAB认证原理

文章目录 1 基础2 使能过程3 Boot flow 1 基础 HAB认证是基于RSA或ECDSA算法的公钥密码学&#xff0c;它用一系列的私钥对image进行加密&#xff0c;然后BootROM在上电后用对应的公钥验证加密的镜像是否被修改。这个密钥结构就是PKI(Public Key Infrastructure)树 (1)normal …

chatgpt赋能python:Python中画笔颜色的函数介绍

Python中画笔颜色的函数介绍 在Python中&#xff0c;我们可以使用turtle模块来绘制图形&#xff0c;其中画笔颜色是非常重要的一部分。画笔颜色可以决定图形的风格和色调&#xff0c;是图形表现的关键因素之一。Python中提供了几种方法来设置画笔颜色。 1. 设置画笔颜色的函数…

ENU、EPSG坐标系科普(三维重建)

ENU和EPSG实际上代表了两个不同的概念&#xff0c;这两者并不是直接对比的。 1. ENU坐标系&#xff1a;ENU坐标系是一种本地切面坐标系&#xff0c;用于表示与地理位置相关的空间数据。在ENU坐标系中&#xff0c;E代表东&#xff08;East&#xff09;&#xff0c;N代表北&…

RabbittMQ快速实战和集群架构

介绍对比: Kafka&#xff1a;topic不能太多&#xff0c;一个缺点&#xff0c;影响Kafka的吞吐量 集群搭建&#xff1a;【单个也是一个集群&#xff08;特殊&#xff09;】 集群搭建&#xff1a;https://blog.csdn.net/p393975269/article/details/129830252 1&#xff1a;默认…

【明解STM32】中断系统理论基础知识篇之中断寄存器功能原理

目录 一、前言 二、寄存器概述 三、NVIC寄存器组 四、SCB寄存器组 五、中断屏蔽寄存器组 六、总结 一、前言 在之前的STM32的中断系统理论基础知识之基本原理及NVIC中&#xff0c;分别中断的基本原理&#xff0c;中断的管理机制和中断的处理流程进行了较为详细的论述&…

SOLIDWORKS钣金成形工具

SOLIDWORKS钣金成形工具主要用来创建使用冲制或压印制作的钣金特征。成形工具的工作原理是&#xff1a;几何体代表冲制或压印形成的凹陷区域&#xff0c;停止面是指工具要被应用到的钣金面&#xff0c;也可以定义移除面&#xff0c;若定义了移除面&#xff0c;则该面会形成通孔…

模拟人生打开显示找不到msvcp120.dll如何修复?msvcp120.dll是什么呢?

如果您在打开模拟人生游戏时遇到了msvcp120.dll文件丢失的错误信息&#xff0c;这可能是由于缺少Microsoft Visual C Redistributable for Visual Studio 2013软件包导致的。遇到这个情况不需要着急&#xff0c;只需要修复一下就可以。msvcp120.dll如何修复&#xff1f;下面就把…

黑马Redis视频教程实战篇(二)

目录 一、什么是缓存&#xff1f; 1.1 为什么要使用缓存&#xff1f; 1.2 如何使用缓存&#xff1f; 二、添加商户缓存 2.1 缓存模型和思路 2.2 代码实现 三、缓存更新策略 2.1 数据库缓存不一致解决方案 2.2 数据库和缓存不一致采用什么方案 四、实现商铺和缓存与数…

SAP-MM发票校验过账到总账

一&#xff0e;概念 SAP的MIRO发票校验&#xff0c;通常是参照采购订单&#xff08;PO&#xff09;生成&#xff0c;但有时会收到无PO参考的发票&#xff0c;例如供应商的运费、质检费等&#xff0c;这些不想过帐到发票项目的物料或成本科目&#xff0c;那么可以过帐到某个总账…

kong网关启用jwt认证插件

认证流程&#xff1a; 1、创建一个用户 2、生成jwt的所需要的key和密钥 3、在https://jwt.io/的生成jwt token 4、启用jwt插件 5、发送请求的时候携带jwt的token信息 官方指导&#xff1a;https://docs.konghq.com/hub/kong-inc/jwt/configuration/examples/ 一、创建一个新的…

深蓝学院C++基础笔记 第 0 章 C++介绍

一、什么是C 1、c 是一门比较流行的编程语言 \qquad ●https://www.tiobe.com/tiobe-index/2、c是C 语言的扩展 ● 更加关注性能 \qquad ● 与底层硬件紧密结合 \qquad \qquad java和python等语相对来说更加关注易用性。 \qquad ● 对象生命周期的精确控制 \qquad \qqua…

冒泡排序小练习(接收键盘录入、拆分、转整、冒泡递减排序、输出)

接收键盘录入(含输入字符串排错)字符串&#xff0c;拆分、转整、冒泡排序(递减)输出。 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简单…… 地址…

unity3d 中场景不显示了

应该是把Layers下面的Nothing打开了

Java学习路线(18)——File、递归、字符集和IO流(上)

一、文件 &#xff08;1&#xff09;概述 File类在java.io.File下&#xff0c;代表操作系统的文件对象&#xff08;文件、文件夹&#xff09;File类提供诸如&#xff1a;定位文件&#xff0c;获取文件信息&#xff0c;删除文件&#xff0c;创建文件等操作 &#xff08;2&…

大数据Doris(三十):Broker Load导入HDFS数据时进行数据过滤

文章目录 Broker Load导入HDFS数据时进行数据过滤 一、创建Doris表 二、准备HDFS数据

使用Axios前后端交互(超详细)建议点赞收藏

1、安装axios 将目录切换到当前项目目录下&#xff0c;执行下面安装命令&#xff1a; npm install --save axios vue-axios 2、将axios挂载到vue实例上或则直接导入组件中 在mian.js中做如下配置&#xff0c;可将axios挂载到vue实例上&#xff1a; import axios from axios…

HNU-电子测试平台与工具2-基于485总线的评分系统

基于485总线的评分系统实验报告 计科210X wolf 202108010XXX 同组成员:wolf、DragonKing、Eliak 验收分数:90 1 实验项目 1.1 项目名称 基于485总线的评分系统 1.2 实验目的 通过本案例加深理解RS485通信方式,实现上位机的主控制器与所有的下位机进行通信。 1.3 实…

高完整性系统:Invariants

目录 1. INVARIANTS 1.1 例子 1.2 正式的证明 1. INVARIANTS 一个不变式需要满足以下三个属性&#xff1a; 当循环开始时&#xff0c;不变式是正确的在每一次循环迭代之后&#xff0c;不变式仍然是正确的当循环条件为假时&#xff0c;不变式能推出循环结束后的条件&#x…

逻辑漏洞学习-身份验证漏洞

逻辑漏洞就是程序在实现业务逻辑上存在的错误&#xff0c;辑漏洞的出现通常是因为程序在设计业务逻辑时考虑不够全面&#xff0c;或者程序员的思维过程存在瑕疵&#xff0c;没有充分考虑到各种可能的情况 大部分程序员在设计的时候&#xff0c;目标是实现功能需求&#xff0c;…