js笔试题 判断数字是否为对称数组(JS笔试题)
二升三笔试(老田)
一.数组扁平化
(将一个多维数组变为一个一维数组 。例如 ,将数组[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¶m2=[1,2,3]¶m3=%7B%22key%22%3A%22value%22%7D¶m4=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中如何对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
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]));二升三笔试(闫)
一.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请求的核心步骤?
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创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!