程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

JS笔试题

发布于2023-05-20 19:15     阅读(2748)     评论(0)     点赞(16)     收藏(1)


二升三笔试(老田)

一.数组扁平化

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

  1. function getArray(arr) {
  2. let res = [];
  3. for (let i = 0; i < arr.length; i++) {
  4. if (Array.isArray(arr[i])) {
  5. res = res.concat(getArray(arr[i]));
  6. } else {
  7. res.push(arr[i]);
  8. }
  9. }
  10. return res;
  11. }
  12. 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]

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

三.求两个数的交集

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

  1. function intersection(arr1, arr2) {
  2. var set1 = new Set(arr1);
  3. var set2 = new Set(arr2);
  4. var result = new Set();
  5. for (var value of set1) {
  6. if (set2.has(value)) {
  7. result.add(value);
  8. }
  9. }
  10. return Array.from(result);
  11. }
  12. var arr1 = [12, 23, 34, 45,21];
  13. var arr2 = [21, 23, 45, 100];
  14. var result = intersection(arr1, arr2);
  15. console.log(result); // [23, 45]

四.最接近三个数之和

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

  1. function threeSumClosest(nums, target) {
  2. let closestSum = nums[0] + nums[1] + nums[2]; // 初始化最接近的三数之和
  3. for (let i = 0; i < nums.length - 2; i++) {
  4. for (let j = i + 1; j < nums.length - 1; j++) {
  5. for (let k = j + 1; k < nums.length; k++) {
  6. const sum = nums[i] + nums[j] + nums[k];
  7. if (Math.abs(sum - target) < Math.abs(closestSum - target)) { // 如果当前的三数之和更接近目标值,则更新最接近的三数之和
  8. closestSum = sum;
  9. }
  10. }
  11. }
  12. }
  13. return closestSum;
  14. }
  15. 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);

  1. // 自己实现一个事件处理机制:(事件绑定,事件触发,事件解绑);
  2. class EventEmitter {
  3. constructor() {
  4. this.events = {};
  5. }
  6. // 绑定事件:
  7. // 参数:
  8. // name:事件名
  9. // callback:事件处理函数
  10. on(name, callback) {
  11. this.events[name] = callback;
  12. }
  13. // 触发事件
  14. // name:事件名
  15. // data:传给事件处理函数的参数
  16. emit(name, data) {
  17. this.events[name](data);
  18. }
  19. // 解绑事件:
  20. // 参数:
  21. // name:事件名
  22. off(name) {
  23. delete this.events[name];
  24. }
  25. }
  26. const event = new EventEmitter();
  27. // 绑定事件
  28. event.on("myclick", function (params) {
  29. console.log("myclick", params);
  30. });
  31. event.on("yourclick", function (params) {
  32. console.log("yourclick", params);
  33. });
  34. function fn01() {
  35. // 触发事件
  36. event.emit("myclick", "hi");
  37. }
  38. function fn02() {
  39. event.emit("yourclick", "hello");
  40. }
  41. function fn03() {
  42. // 取消绑定
  43. event.off("myclick");
  44. }

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

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

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

     

  1.     var data = [{
  2.              name: "uc",
  3.              value: 5
  4.          }, {
  5.              name: "amap",
  6.              value: 2
  7.          }, {
  8.              name: "ali",
  9.              value: 3
  10.          }
  11.        ]
  12. function bubbleSort(arr, compareFn) {
  13. for (var i = 0; i < arr.length; i++) {
  14. for (var j = 0; j < arr.length - 1 - i; j++) {
  15. if (compareFn(arr[j], arr[j + 1]) > 0) {
  16. [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
  17. }
  18. }
  19. }
  20. return arr;
  21. }
  22. function compareByValue(a, b) {
  23. return a.value - b.value;
  24. }
  25. 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]}本平台可运行代码,建议在平台跑通后再提交

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

四道题(老田)

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

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

 二、请把下面的对象数组变成对象嵌套。

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

  1. // let arr = [
  2. // {
  3. // id: 1,
  4. // name: "张一",
  5. // parentId: null
  6. // },
  7. // {
  8. // id: 2,
  9. // name: "张二",
  10. // parentId: 1
  11. // },
  12. // {
  13. // id: 3,
  14. // name: "张三",
  15. // parentId: 1
  16. // },
  17. // {
  18. // id: 4,
  19. // name: "张四",
  20. // parentId: 2
  21. // },
  22. // {
  23. // id: 5,
  24. // name: "张五",
  25. // parentId: 2
  26. // },
  27. // {
  28. // id: 6,
  29. // name: "张六",
  30. // parentId: 3
  31. // },
  32. // {
  33. // id: 7,
  34. // name: "张七",
  35. // parentId: 4
  36. // },
  37. // {
  38. // id: 8,
  39. // name: "张八",
  40. // parentId: 6
  41. // }
  42. // ]
  43. //方法一:======================================================================
  44. function arrToJson(root) {
  45. // 2、循环数组,找子元素
  46. let children = arr.filter(item => item.parentId == root.id);
  47. if (children.length > 0) {
  48. root.children = children;
  49. children.forEach(item => {
  50. arrToJson(item);
  51. })
  52. };
  53. }
  54. // 1、先找的根元素;
  55. let root = arr.filter(item => item.parentId == null)[0]
  56. arrToJson(root);
  57. console.log(root);
  58. //方法二:======================================================================
  59. function arrToJSON(arr) {
  60. let root;
  61. arr.forEach(item => {
  62. if(item.parentId!=null){
  63. // 如果有父级
  64. // 找到父级
  65. let parentObj = arr.filter(parentItem=>parentItem.id===item.parentId)[0];
  66. // 给父级增加children属性(数组)
  67. !parentObj.children && (parentObj.children=[]);
  68. // 把自己添加到父级的children属性(数组)
  69. parentObj.children.push(item);
  70. }else{
  71. root = item;
  72. }
  73. });
  74. return root;
  75. }
  76. console.log(arrToJSON(arr));
  77. console.log(arr.length);

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

  1. function add(x) {
  2. return {
  3. multi(y) {
  4. return {
  5. div(z) {
  6. return x*y/z;
  7. }
  8. }
  9. }
  10. };
  11. }
  12. console.log(add(2).multi(9).div(3)); // 输出6
  13. console.log(['1', '2', '3'].map(parseInt))

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

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

二升三笔试(奚)

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

  1. 方式一
  2. function norepeat(arr){
  3. var newarr = [];
  4. for(var i = 0;i<arr.length;i++){
  5. if(newarr.indexof(arr[i]) == -1){
  6. newarr.push(arr[i])
  7. }
  8. }
  9. return newarr;
  10. }
  11. 方式二
  12. function norepeat(arr){
  13. var newarr = arr;
  14. var obj = {};
  15. for(var i = 0;i<arr.length;i++){
  16. obj[arr[i]] = 1;
  17. }
  18. return Object.keys(obj).map(item=>Number(item));
  19. }
  20. 方式三
  21. function norepeat(arr){
  22. var newarr = arr;
  23. newarr.sort();
  24. for(var i = 0;i<newarr.length;i++){
  25. if(arr[i] == arr[i+1]){
  26. arr.splice(i,1)
  27. i--;
  28. }
  29. }
  30. return newarr;
  31. }
  32. 方式四
  33. function norepeat(arr){
  34. return Array.from(new Set(arr));
  35. }

二. 请写出常见的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中如何对dom元素进行删除和复制呢

①父元素.removeChild(子元素);

②被复制的元素.cloneNode(bool);bool是一个布尔值

    1或true:表示复制元素本身以及复制该元素下的所有子元素。

    0或false:表示仅仅复制元素本身,不复制该元素下的子元素。

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

①概念

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

②变量的生命周期

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

③js垃圾回收方式有两种方式: 标记清除、引用计数

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

六.请说出你对this的理解

①this的概述

this是Javascript语言的一个关键字,它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用

②this指向

    1.与事件体连用,代表触发事件的元素本身

    2.与普通函数连用,代表调用该函数的对象

    3.与构造函数连用时,代表new出来的对象

    4.与箭头函数连用时,箭头函数没有this 是,他的this是他父元素的前缀

修改this指向的方式

    1.使用that

    2.使用.bind( )

        Object.bind(this,obj1,obj2,obj3) :如果 bind 的第一个参数为空,则默认指向全局对象

        bind()方法只会返回一个函数,并不会执行函数。

    3.使用.apply() 

        Object.apply(this,arguments):apply 只能写两个参数,第一个参数表示改变后的调用这个函数的对象,即this要指向的对象;第二个参数是一个数组,用于存放要传的参数,可以用arguments获得。如果 apply 的第一个参数为空,则默认指向全局对象

    4.使用.call()

        Object.call(this,obj1,obj2,obj3) :call 可以写多个参数,第一个参数表示改变后的调用这个函数的对象,即this要指向的对象;如果 call 的第一个参数为空,则默认指向全局对象

七.函数的节流和防抖请描述

       节流就是减少流量,将频繁触发的事件减少,并每隔一段时间执行。即,控制事件触发的频率
防抖就是防止抖动,避免事件的重复触发

八.DOM怎样添加、移除、移动、复制、创建和查找节点

①创建  :document.createElement("标签名")  返回值:创建好的标签

②尾部追加 :父节点.appendChild(子节点)  返回值:无

③删除: 节点.remove()   父节点.removeChild(子节点)  返回值:无

④插入(eg: 在第2个之前插入一个创建好的节点)

语法:父节点.insertBefore(新节点,谁的前面的那个谁)  返回值:无

⑤替换 (eg: 创建一个新的,把 原有的替换掉)

语法: 旧节点父节点.replaceChild(新节点,旧节点)  返回值:无

⑥克隆节点:节点.cloneNode(true/false) ()内什么都不写,默认就是false

注意点:true代表克隆自身标签以及后代的所有内容

false只代表克隆自身标签  返回值:克隆出来的

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

①Promise的概念

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

②Promise的两个特点

    1.对象的状态不受外界影响

        Promise 有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和                    Rejected(已失败)

    2.一旦状态改变,就不会再变

        状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected

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

    1. 对象方法:then,catch

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

2.类方法: all ,race

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

⑤总结Promise的使用步骤

1、找到(曾经的)异步操作的代码,放在Prmoise构造函数的参数(函数)里 2、参数(函数)的第一个参数resolve是成功时调用的函数,对应then方法(函数)的第一个参数 3、参数(函数)的第二个参数reject是失败时调用的函数,对应then方法(函数)的第二个参数


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

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

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

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

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

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

  1. function getLight(name, num, color) {
  2. document.getElementsByClassName(name).style.backgroundColor = color;
  3. document.getElementsByClassName(name).innerHTML = num;
  4. return new Promise(function (resolve, reject) {
  5. let myTimer = setInterval(function (params) {
  6. num--;
  7. if (num <= 0) {
  8. num = 0;
  9. clearInterval(myTimer);
  10. myTimer = undefined;
  11. document.getElementsByClassName(name).style.backgroundColor = "white";
  12. resolve();
  13. }
  14. document.getElementsByClassName(name).innerHTML = num;
  15. }, 1000)
  16. })
  17. }
  18. function shanshan() {
  19. getLight(red, 5, red).then(function () {
  20. return getLight(green, 5, green)
  21. }).then(function () {
  22. return getLight(yellow, 5, yellow)
  23. }).then(shanshan);
  24. };
  25. shanshan();

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

  1. const first = () => (new Promise((resolve, reject) => {
  2. console.log(3);//同步代码
  3. let p = new Promise((resolve, reject) => {
  4. console.log(7);//同步代码
  5. setTimeout(() => {
  6. console.log(5);//宏任务
  7. resolve(6);
  8. }, 0)
  9. resolve(1);
  10. });
  11. resolve(2);
  12. p.then((arg) => {
  13. console.log(arg);
  14. });
  15. }));
  16. first().then((arg) => {
  17. console.log(arg);
  18. });
  19. console.log(4);//同步代码
  20. // 输出结果为3,7,4,1,2,5

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

  1. // 求1-100的素数
  2. function getSuNum(num) {
  3. let str = '';
  4. for (let i = 2; i < num; i++) {
  5. for (let j = 2; j < i; j++) {
  6. if (i % j === 0) {
  7. break;
  8. } else if (i === j) {
  9. str += i + " "
  10. }
  11. }
  12. return str;
  13. }
  14. console.log(getSuNum(100));
  15. }

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

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

二升三笔试(闫)

一.Dom操作的api有哪些(至少10个)?

①节点查找相关的API: 

document.getElementById ;//根据ID查找元素,大小写敏感,有多个结果,返回第一个    document.getElementsByClassName ;//根据类名查找元素,多个类名用空格分隔,返回一个    document.getElementsByTagName ;//根据标签查找元素,表示查询所有标签,返回一个    document.getElementsByName ;//根据元素的name属性查找,返回一个 NodeList      document.querySelector ;//返回单个Node,如果匹配到多个结果,只返回第一个       document.querySelectorAll ;//返回一个 NodeList 

②节点创建修改相关的API:

创建  :document.createElement("标签名")  返回值:创建好的标签

尾部追加 :父节点.appendChild(子节点)  返回值:无

删除: 节点.remove()   父节点.removeChild(子节点)  返回值:无

插入:父节点.insertBefore(新节点,谁的前面的那个谁)  返回值:无

替换 : 旧节点父节点.replaceChild(新节点,旧节点)  返回值:无

克隆节点:节点.cloneNode(true/false) 

③节点关系API:

 父找子: childNodes   children   firstElementChild     lastElementChild

 子找父: parentNode

 兄弟节点: nextElementSibling   previousElementSibling

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

①typeof 判断变量类型:在JS中数组是一种特殊的对象, typeof 方法会返 Object

② Array.isArray 判断变量类型:返回值为布尔值,如果是数组则为 true,否则false

③ instanceof 判断数组类型:实例化一个对象时,该对象的原型链中包含它所属类的原型对象,利用这个特性,可以使用 instanceof 来判断该对象是否为数组类型

三.数组的方法都有哪些(至少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一样,只不过是从后向前找

四.请说一下你对Promise的理解?

Promise 是异步编程的一种解决方案,是一个构造函数,自身有all、reject、resolve等方法,实例对象上有then、catch等方法,所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作,如ajax请求)的结果

五.说一说this在不同场景下的指向?

  1.与事件体连用,代表触发事件的元素本身

  2.与普通函数连用,代表调用该函数的对象

  3.与构造函数连用时,代表new出来的对象

  4.与箭头函数连用时,箭头函数没有this ,它的this是他父元素的前缀

六.简述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请求的核心步骤?

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

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

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

 二.实现数组/对象的深拷贝

  1. // 实现对象深拷贝:for循环 + 递归=========================================================
  2. function copyObj(obj) {
  3. var newobj = {};
  4. for (var key in obj) {
  5. if (typeof obj[key] == 'object') {
  6. newobj[key] = copyObj(obj[key]);//发现 obj的键对应的值是复杂数据类型,让复杂数据类型在进行函数的调用
  7. } else {
  8. newobj[key] = obj[key];// 向newobj添加键值对,键是key,值是key对应的值
  9. }
  10. }
  11. return newobj;
  12. }
  13. var obj = { name: "zs", wife: { name: "zs的妻子" } }
  14. var newobj = copyObj(obj);
  15. console.log(obj);//{name: 'zs', wife: {…}}
  16. console.log(newobj);//{name: 'zs', wife: {…}}
  17. obj.wife.name = 'ls的妻子'
  18. console.log(obj.wife.name);//ls的妻子
  19. console.log(newobj.wife.name);//zs的妻子
  20. // 实现数组深拷贝:JSON.parse(JSON.stringify())===========================================
  21. var arr = [12, [12, 34, 56, 67], [12, 34, 65]];
  22. var newarr = JSON.parse(JSON.stringify(arr))
  23. console.log(newarr);
  24. // 第一层相互受影响吗? 不影响
  25. arr[0] = 10
  26. console.log(arr[0]); // 10
  27. console.log(newarr[0]); // 12
  28. // 第二层相互受影响吗? 不影响
  29. arr[1][0] = '新'
  30. console.log(arr[1][0]); // "新"
  31. console.log(newarr[1][0]); // 12
  32. // 封装一个函数,既能实现数组的拷贝,也能实现对象的拷贝==================================
  33. function copyEle(ele) {
  34. if (ele instanceof Array) { // 如果ele是数组的类型
  35. var newarr = [];//创建一个新的空间
  36. for (var i = 0; i < arr.length; i++) {
  37. if (typeof (arr[i]) == 'Object') {
  38. newarr.push(copyArr(arr[i]))
  39. } else {
  40. newarr.push(arr[i])
  41. }
  42. }
  43. return newarr;
  44. } else if (ele instanceof Object) { // 判断传入的是不是对象类型
  45. var newobj = {};
  46. for (var key in obj) {
  47. if (typeof obj[key] == 'object') {
  48. newobj[key] = copyObj(obj[key]);//发现 obj的键对应的值是复杂数据类型,让复杂数据类型在进行函数的调用
  49. } else {
  50. newobj[key] = obj[key];// 向newobj添加键值对,键是key,值是key对应的值
  51. }
  52. }
  53. return newobj;
  54. }else{
  55. return "请传入数组或者对象类型"
  56. }
  57. }

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

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

四.对象转为查询字符串格式

  1. function getObj(obj) {
  2. var str = '';
  3. for (var k in obj) {
  4. str += `${k}=${obj[k]}&`
  5. str = str.slice(0, -1)
  6. }
  7. return str;
  8. }
  9. let newobj = {
  10. name: "zs",
  11. sex: "男",
  12. age: 18
  13. }
  14. console.log(getObj(newobj));//name=zssex=男age=18
  15. ========================================================================================
  16. let obj = {
  17. name: "capper",
  18. age: 18,
  19. sex: "男"
  20. }
  21. let url = "https://www.antgroup.com?"
  22. function getStr(url, obj) {
  23. let str = "";
  24. for (let key in obj) {
  25. str += `${key}=${obj[key]}&`
  26. }
  27. str = `${url}${str}`
  28. return str;
  29. }
  30. console.log(getStr(url, obj));

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

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

输出:"fl"

  1. function publicPrefix(arr) {
  2. let i = 0;//字符串的下标。
  3. while (true) {
  4. let char = arr[0][i];//数组第一个元素的第i个字符
  5. // j是数组的下标
  6. for (let j = 1; j < arr.length; j++) {
  7. if (char != arr[j][i]) {
  8. return arr[0].substring(0, i);
  9. }
  10. }
  11. i++;
  12. if (i > arr[0].length - 1) {
  13. return arr[0];
  14. }
  15. }
  16. }
  17. console.log(publicPrefix(["flower", "flow", "flight"]));//fl

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

  1. const promise1 = new Promise((resolve, reject) => {
  2. console.log('promise1');//同步
  3. resolve();
  4. })
  5. promise1.then(() => {
  6. console.log(3);//微任务
  7. })
  8. console.log(1);//同步
  9. const fn = () => new Promise((resolve, reject) => {
  10. console.log(2);//同步
  11. resolve('success')
  12. })
  13. fn().then((res) => {
  14. console.log(res)//微任务
  15. })
  16. console.log('start');//同步
  17. // 输出结果为:promise1,1,2,start,3,success




所属网站分类: 技术文章 > 博客

作者:我喜欢css

链接:http://www.qianduanheidong.com/blog/article/528194/898aabc94a320f3fea3d/

来源:前端黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

16 0
收藏该文
已收藏

评论内容:(最多支持255个字符)