JavaScript基础篇
1,以下输出什么
for(var i =1; i<=5;i++){
setTimeout(function timer(){
console.log(i);
},i*1000)
}
知识点:
JavaScript引擎是单线程运行的,浏览器无论在什么时候都有且仅有一个线程在运行JavaScript程序。编程过程中的setTimeout(类似的还有setInterval、Ajax)为异步执行
解析:实际结果是1-6秒都是输出6,这是为什么呢?这时就要去了解setTimeout函数的运行机制了,它会等到for循环全部运行完毕后,才会执行fun函数,当for循环结束后此时i的值已经变成了6因此虽然定时器跑了5秒,控制台上的内容依然是6(当定时器跑完一秒之后for循环已经做完了)
答案参考地址: https://blog.csdn.net/xmx1314520/article/details/80927422
2,以下输出什么
function test(x, y, z) {
console.log(test.length);
console.log(arguments.length);
console.log(arguments[2]);
}
test(1, 2);
答案: 3 2 true undefined
解析:
- test.length是返回的函数的形参个数,所以为3;
- arguments.length返回的是函数调用时的实参个数,所以为2;
- arguments.callee:初始值就是正被执行的 Function 对象,用于在函数内部调用自身,arguments对象本身是个由函数调用时传入的实参组成的伪数组,访问单个参数的方式与访问数组元素的方式相同。
只传入了两个参数,自然为undefined.
3,以下输出什么
var a = 10;
a.pro = 10;
console.log(a.pro + a);
var s = "hello";
s.pro = "world";
console.log(s.pro + s);
答案:NaN undefinedhello
解析:JavaScript引擎内部在处理对某个基本类型 a进行形如a.pro的操作时,会在内部临时创建一个对应的包装类型(对数字类型来说就是Number类型)的临时对象,并把对基本类型的操作代理到对这个临时对象身上,使得对基本类型的属性访问看起来像对象一样。但是在操作完成后,临时对象就销毁了,下次再访问时,会重新建立临时对象,当然就会返回undefined了
4,以下输出什么
var f = 1;
if (!f) {
var a = 10;
}
function fn() {
var b = 20;
c = 30;
}
fn();
console.log(a);
console.log(c);
console.log(b);
答案:undefined 30 报错:b is not defined
解析:
- 没有用var声明的是全局变量,即便在函数内部;
- 只有在function内部新声明的才是局部变量,在if,while,for等声明的变量其实是全局变量(除非本身在function内部)
- 因为变量提升,虽然if块的内容没执行,但是预解析阶段会执行var a,只是没有赋值而已,因此打印a是undefined而打印b会报错
5,以下输出什么
(function () {
// var a = (b = 5);
var a=b=5
})();
// console.log(b);
// console.log(a);
答案:5 Uncaught ReferenceError: a is not defined
解析:在这个立即执行的函数表达式中(IIFE)包含两个赋值操作,其中 a 使用 var 关键字进行声明,因此其属于函数内部的局部变量(仅存在于函数中),相反,b 被分配到全局命名空间,可以看作 var a = 5; b = 5;
另一个需要注意的时,这里没有在函数内部使用严格模式,如果启用了严格模式,代码会在输出 b 时报错 Uncaught ReferenceError: b is not defined ,需要记住的是,严格模式要求你显示的引用全局作用域
6,说说call和apply的区别
解析:Function.prototype.call()与Function.prototype.apply()方法的作用都是一样的 —— 改变this指向。
唯一的区别就是参数不同:
-
Function.apply(obj,args):
obj: 这是一个对象,将代替Function里面的this对象
args:这是一个数组,它将作为参数传递给Function(args —> arguments) -
Function.call(obj,value1,value2…)
obj: 这是一个对象,将代替Function里面的this对象
value1,value2…: 是参数列表
关于性能问题: call()比apply()性能要好
在ES6中即使参数是数组,也可以使用call(),使用扩展运算符…即可。
let array = [1, 2, 3, 4];
xxx.call(obj, ...array);
apply()还用一些妙用:例如找出数组中的最大最小值、Array.prototype.push使用apply可以将一个数组添加到另一个数组的尾部
知识点链接:https://www.cnblogs.com/shaozhu520/p/11463192.html
7,数组pop(),push(),shift(),unshift()有什么区别
- shift()方法:移除数组中的第一项并返回该项
- push()方法:从数组末端添加项
- unshift()方法:在数组的前端添加项
- pop()方法:从数组末端移除项
知识点链接:https://blog.csdn.net/qwe502763576/article/details/79055682
8, 以下输出什么
let a=101;
let b=a>100&&(a=70)
let c=(a>50)||(a=25)
console.log(a,b,c);
答案:70 70 true
知识点链接:https://blog.csdn.net/m0_37263637/article/details/79964874
9,说说==和===区别
答案:==表示等同,===表示恒等。==只比较内容,而===既比较内容也比较数据类型。
知识点链接:https://www.cnblogs.com/mycnblogs-guoguo/p/10101355.html
10,例举JavaScript基本数据类型和引用数据类型
答案:
基本数据类型:Null、Undefined、Boolean、String、Number。
引用数据类型:Object、Array、Date、RegExp
知识点链接:https://blog.csdn.net/weixin_41646716/article/details/81700761
11,例举浏览器本地存储几种方式,并描述他们不同
答案:
-
cookie
cookie算是比较早的技术,最初是为了记录http的状态,提高访问速度。cookie是服务器"种植"在客户端的key-value形式文本文件。但同时客户端也能操作cookie。
特点:大小:cookie的大小限制在4k。每个域名下cookie的个数现在在20个。
在客户端请求服务器端和服务器响应时,cookie始终被携带在http请求中,即使不需要(造成流量浪费)。这也是限制cookie大小的原因。
客户端可以通过document.cookie操作cookie,并不安全。
cookie可以设置过期时间、路径、域和httpOnly等字段。如果设置了过期时间,cookie会保存在硬盘里,知道到了设定的过期时间才会失效。若未设置过期时间,在浏览器窗口关闭时,cookie就失效了。路径和域两个字段限制了cookie的作用范围。httpOnly设置为true,则js不能通过document.cookie操作cookie。 - localStorage
它也是采用key-value的形式存储数据,但是它与cookie有很大的区别
特点:
对比着来,localStorage能保存更大的数据,标准浏览器是5Mb。
localStorage保存在客户端,不随着请求发送给服务器,避免了流量的浪费。
客户端可以通过:setItem、getItem方法访问localStorage。
并且,localStorage没有过期时间,如果不手动清除,数据就永远不会过期,一直保存在浏览器当中。
存储的信息在同一域中是共享的。 -
sessionStorage
特点:
与localStorage不同的是,sessionStorage并不持久化,在窗口关闭那一刻,sessionStorage会被清除。
存储的信息是会话级别的,同域也是不能共享的。关闭当前标签页,sessionStorage即失效。 -
session(附加)
上面提到了cookie,顺带提一下session。客户端第一次访问服务器,服务器种植一个cookie,保存唯一的sessionId。后面客户端再次访问,会读取此sessionId,随即能在服务端读取到此id保存的会话对象。
特点:
session是基于cookie的,由于session在客户端不可被修改,相对于cookie来说安全,所以可存放一些重要数据。
数据保存在服务器端,客户端通过sessionId,读取到相对应的数据。
12,说说es6的‘=>’的作用
答案:
- 类似于匿名函数,在某些情况下使用,可减少代码量
- 代码简洁,this提前定义
- 代码太过简洁,导致不好阅读
- this提前定义,导致无法使用js进行一些在ES5里面看起来非常正常的操作(若使用箭头函数,在监听点击事件的回调函数中,就无法获取到当前点击的元素咯
- 总的来说,箭头函数只是一种函数的简写,有其利弊,可用可不用,看大家心情,当然也得用的正确
知识点链接:https://blog.csdn.net/qq_32614411/article/details/80897256?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.nonecase
13,简写出一个数组的去重算法
答案:
//es6
function deleteRepeat(arr){
const seen=new Map(){
return arr.filter((a)=>!seen.has(a)&&seen.set(a,1));
}
}
//or
function deleteRepeat2(arr){
return Array.form(new Set(arr))
}
知识点学习:https://www.cnblogs.com/luxueping/p/5593910.html
14,以下代码依次输出的内容是
setTimeout(function(){
console.log(1);
},0);
new Promise(function executor(resolve){
console.log(2);
for(var i=0; i<10000;i++){
i=9999 && resolve()
}
console.log(3);
}).then(function(){
console.log(4);
})
console.log(5);
答案:2,3,5,4,1
知识点链接:https://juejin.im/post/59e85eebf265da430d571f89
15,jquery的ajax返回的是promise对象吗?
答案:是的,但是在jQuery中,不仅只有Ajax函数(.ajax,.get, .post)可以返回Promise对象,动画函数也可以返回Promise对象
知识点链接:https://blog.csdn.net/mzrxlxr/article/details/81475301
16,写出以下输出什么
let node = {
type:"ldentifier",
name:"foo"
};
let {type,name,value} = node;
console.log(type,name,value);
答案:ldentifier foo undefined
知识点:https://www.cnblogs.com/tfxz/p/12838739.html
17,用js算法实现一个函数,函数可以把一个数组拆分多个数组,并且按每3个一组。如[1,2,3,4,5,6,7,8,9,10]经过此函数可以变成[[1,2,3],[4,5,6],[10]]
<script>
// 方法一
var arr = [1,2,3,4,5,6,7,8,9,10];
let len = Math.floor(arr.length / 3)
var i =0;
var newArr = []
function getArr() {
const substringArr= arr.slice(i*3,i*3+3)
newArr.push(substringArr)
console.log(substringArr);
i++;
//回调
if(i<len){
getArr()
}
}
getArr()
if(arr.length % 3 ==1){
let one = newArr.push([arr.length])
console.log(one);
}
if(arr.length % 3 ==2){
let one = newArr.push([arr.length-1,arr.length])
console.log(one);
}
console.log(newArr);
//方法二
function onArrTwoArr(data){
let newData = [];
for(let i=0; i<Math.ceil(data.length/3);i++){
console.log(data.length/3);
newData[i]=[]
newData[i].push(data[i*3])
// newData[i].push(data[i*3+1])
}
return newData
}
var newArr2 =onArrTwoArr(arr)
console.log(newArr2);
</script>
18,用js算法实现把[{name:'张三',class:'一班'}],{name:‘李四’,class:'二班'},...],这样一个人员年龄array经行按班级分组
答案:
19,什么是浏览器跨域访问?有什么解决手段?
答案:同源策略
现在对跨域的解决方法大概有以下几种:
- 通过jsonp跨域
- document.domain + iframe跨域
- location.hash + iframe
- window.name + iframe跨域
- postMessage跨域
- 跨域资源共享(CORS)
- nginx代理跨域
- nodejs中间件代理跨域
- WebSocket协议跨域
知识点链接:https://blog.csdn.net/wonking666/article/details/79159180
网友评论