HTML相关
1、XHTML和HTML有什么区别
HTML是一种基本的WEB网页实际语言,XHTML是一种基于XML的置标语言
最主要的不同:
- XHTML 元素必须被正确的嵌套;
- XHTML 元素必须被关闭;
- XHTML 标签名必须用小写字母;
- XHTML 文档必须拥有根元素。
2、什么是语义化的HTML?
- 直观的认识标签,对于搜索引擎的抓取有好处,用正确的标签做正确的事。HTML语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析;
- 在没有css样式加持的情况下也以一种文档格式显示,并且是容易阅读的。搜索引擎的爬虫依赖于标记来确定上下文和各个关键字的权重,利于SEO。
- 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。
3、常见的浏览器内核有哪些?
- Trident内核 IE、360、搜狗等
- Gecko内核 Netscape6及以上版本、Firefox
- Presto内核 Opera7及以上
- Webkit Safari、Chrome等
4、H5有哪些新特性?移除了哪些元素?如何处理HTML5新标签的浏览器兼容问题?
新特性
- canvas绘图;
- 本地离线存储localStorage长期存储数据,浏览器关闭后数据不丢失;
- sessionStorage数据在浏览器关闭后会自动删除;
- 用于媒体回放的video和audio;
- 语义化更好的内容标签如article、footer、header、nav、setion;
- 表单控件 calendar、date、time、email、url、search;
- 新的技术 web worker、web socket、geolocation。
移除元素
- 纯表现元素 font、big、center、u、tt、s;
- 对可用性产生负面影响的元素:frame、frameset、noframes
兼容
IE8/IE7/IE6支持通过document.createElement
方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签。
5、如何实现浏览器内多个标签页之间的通信?
调用 localStroage、cookie 等本地存储方式
6、HTML5为什么只需要写!DOCTYPE HTML?
HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照他们应该的方式来运行);而HTML4.0基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。
7、Doctype作用?标准模式与兼容模式各有什么区别?
!DOCTYPE声明位于HTML文档中的第一行,处于html标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。
标准模式的排版和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
8、label的作用是什么?怎么用?
label标签是用来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。
用法:
<label for = "Name">Number:</label>
<input type="text" name="Name" id="Name" />
or
<label>Data:<input type="text" name="B" /><label>
CSS相关
1、如何居中div?如何居中一个浮动元素?
//居中div
margin: 0 auto
//居中浮动元素
float:left;
position:relative;
left:50%;
//居中绝对定位div
position:absolute;
top: 50%;
left: 50%;
margin:-100px 0px 0px -100
2、经常遇到的浏览器兼容性有哪些?简述原因和解决办法?
1)不同浏览器的标签,默认的margin和padding不同
解决方案:加一个全局的*{margin:0;padding:0;}来统一。
2)IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。
解决方案:在float的标签样式控制中加入 display:inline;将其转化为行内属性。
3)在IE6,IE7中元素高度超出自己设置高度。
原因:IE8以前的浏览器中会给元素设置默认的行高的高度导致的。
解决方案:加上overflow:hidden或设置line-height为更小的高度。
4)min-height在IE6下不起作用
解决方案:添加 height:auto !important;height:xxpx;其中xx就是min-height设置的值。
5)a(有href属性)标签嵌套下的img标签,在IE下会带有边框
解决方案:加上a img{border:none;}样式。
6)IE6下border:none无效
解决方案:用:border:0或border:0 none;或border:none:border-color:transparent;,推荐用第三种方案。
3、CSS3的新特性
- 选择器(E:last-child)
- @Font-face
- 圆角
- 多列布局
- 阴影效果
- 弹性盒子
- 特效
- 渐变效果
4、CSS优化、提高性能的方法有哪些?
- 加载性能,不要用import、压缩等,减少文件体积,减少阻塞加载,提高并发
- 选择器性能 建议使用ID,类选择器,避免属性,后代选择器,通用选择器。组合选择器,优化最右边的关键选择器。
- 渲染性能 是不是大量使用了 text-shadow?是不是开了字体抗锯齿?CSS 动画怎么实现的?合理利用 GPU 加速了吗?
- 可维护性能 命名合理吗?结构层次设计是否足够健壮?对样式进行抽象复用了吗?
5、简要说说CSS的元素分类?
- 块级元素:div、h1、form、ul、li、p
- 行内元素:span、a、label、input、img
- CSS盒模型:内容、border、margin、padding
6、CSS清除浮动的几种方法
- 父级 div 定义 height;
- 父级 div 定义 display:table;
- 结尾处使用带 clear 属性的空 div;
- 使用 CSS 的 overflow 属性(hidden、auto);
- 使用 CSS的 :after 伪元素。
7、display有哪些值?说明他们的作用。
- block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
- none 缺省值。象行内元素类型一样显示。
- inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
- inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
- list-item 象块类型元素一样显示,并添加样式列表标记。
- table 此元素会作为块级表格来显示。
- inherit 规定应该从父元素继承 display 属性的值。
8、position的值, relative和absolute分别是相对于谁进行定位的?
- absolute 生成绝对定位的元素, 相对于最近一级的 定位不是 static 的父元素来进行定位。
- fixed(老IE不支持)生成绝对定位的元素,通常相对于浏览器窗口或 frame 进行定位。
- relative 生成相对定位的元素,相对于其在普通流中的位置进行定位。
- static 默认值。没有定位,元素出现在正常的流中
- sticky 生成粘性定位的元素,容器的位置根据正常文档流计算得出
9、CSS引入的方式有哪些? link和@import的区别是?
内联 内嵌 外链 导入
区别:同时加载
前者无兼容性,后者CSS2.1以下浏览器不支持
Link 支持使用javascript改变样式,后者不可
10、CSS选择器 ~ 和 + 有什么区别?
~
匹配所有兄弟元素,+
匹配紧挨着的兄弟元素。
另外:
>
匹配所有子元素,(空格)
匹配所有后代元素。
11、CSS中的常见单位?
- px: 绝对单位,页面按精确像素展示;
- em: 相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算,整个页面内1em不是一个固定的值;
- rem: 相对单位,可理解为“root em”,相当于根节点html的字体大小来计算。
- vm: viewpoint width,视窗宽度,1vm等于视窗宽度的1%;
- vh: viewpoint height,视窗高度,1vh等于视窗高度的1%。
JS相关
1、谈一谈JavaScript作用域链
当执行一段 JavaScript 代码(全局代码或函数)时,JavaScript 引擎会为其创建一个作用域(又称为执行上下文),在页面加载后会首先创建一个全局作用域,然后每执行一个函数,会建立一个对应的作用域,从而形成一条作用域链。每个作用域都有一条对应的作用域链,链头是全局作用域,链尾是当前函数作用域。
作用域链的作用是用于解析标识符,当函数被创建时(不是被执行),会将this、arguments、命名参数和该函数中所有局部变量添加到当前作用域中。当JavaScript需要查找变量x的时候(这个过程被称为解析),它首先会从作用域链中的链尾(也就是当前作用域)进行查找是否有x属性,如果没有找到就顺着作用域链继续查找,直到查找到链头(也就是全局作用域链),仍未找到该变量的话,就认为这段代码的作用域链上不存在x变量,并抛出一个引用错误的异常。
2、原型是什么?原型链是什么?
JavaScript中的每个对象都有一个prototype属性,我们称之为原型,而原型的值也是一个对象,因此它也有自己的原型,这样就串联起来了一条原型链,原型链的链头是object,它的prototype比较特殊,值为null。
原型链的作用是用于对象继承,函数A的原型属性(prototype property)是一个对象,当这个函数被用作构造函数来创建实例时,该函数的原型将被作为原型赋值给所有实例对象,比如我们创建一个数组,数组的方法便从数组的原型上继承而来。
原型五项规则
- 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了null除外)
- 所有的引用类型(数组、对象、函数),都有一个
__proto__
(隐式原型)属性,属性值是一个普通的对象;
- 所有的引用类型(数组、对象、函数),都有一个
- 所有的函数,都有一个prototype(显式原型)属性,属性值也是一个普通的对象;
- 所有的引用类型(数组、对象、函数),
__proto__
属性值指向它的构造函数的prototype属性值;
- 所有的引用类型(数组、对象、函数),
- 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的
__proto__
(即它的构造函数的prototype)中寻找。
- 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的
3、构造函数,原型对象,实例对象三者之间的关系
每创建一个函数,该函数都会自动带有一个prototype属性。该属性是一个指针,指向一个对象,该对象称之为原型对象。
原型对象上默认有一个属性constructor,该属性也有一个指针,指向其关联的构造函数。
通过调用构造函数产生的实例对象,都拥有一个内部属性,指向了原型对象。其实例对象能够访问原型对象上的所有对象和方法。
总结:三者的关系是,每个构造函数都有一个原型对象,原型对象上包含着一个指向构造函数的指针,而实例都包含着一个指向原型对象的内部指针。通俗的讲,实例可以通过内部指针访问到原型对象,原型对象可以通过constructor找到构造函数。
4、什么是闭包?闭包的作用?
闭包就是函数中的函数,里面的函数可以访问外面函数的变量,外面的变量是这个内部函数的一部分。
闭包就是函数能够记住并访问它的词法作用域,即使当这个函数在它的词法作用域之外执行时。
闭包作用
- 使用闭包可以访问函数中的变量;
- 可以将变量长期保存在内存中,生命周期比较长。
闭包使用场景
- 函数作为返回值
- 函数作为参数传递
闭包不能滥用,否则会导致内存泄漏,影响网页的性能。闭包使用完成后,要立即释放资源,将引用变量指向 null 。
4、JSON是什么
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它是基于 JavaScript 的一个子集。数据格式简单,易于读写,占用宽带小。是前后台交互最常见的一种数据格式。JSON也只不过就是一个js对象而已。
常用方法
JSON.stringify({name: 'xiaoxin', age: 20}) //对象转为字符串
JSON.parse('{name: \'xiaoxin\', age: 20}') //字符串转为对象
5、JavaScript有几种类型的值?区别是什么?
两大类
- 栈: 原始数据类型(Undefined、Null、Boolean、Number、String、Symbol);
- 堆: 引用数据类型(Object、Array、Function)
区别
原始数据类型 直接存储在栈(stack)中的简单数据段,占用空间小、大小固定,属于被频繁使用数据。
引用数据类型 存储在堆(heap)中的对象,占用空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,首先会检索其在栈中的地址,然后从堆中获取实体。
6、谈谈对this的理解?
this 表示当前对象,this 的指向是根据调用的上下文来决定的,默认指向 window 对象,指向 window 对象时可以省略不写,例如
this.alert() === window.this.alert() === alert()
,调用的上下文环境包括全局和局部。
执行时才能确认值,定义时无法确认
全局环境 就是在<script></script>
中,这里的 this 始终指向的是 window 对象;
局部环境
- 在全局作用域下直接调用函数,this 指向 window(普通执行);
- 对象函数调用,哪个函数调用就指向哪个对象(对象属性执行);
- 使用 new 实例化对象,在构造函数中 this 指向实例化对象(构造函数执行);
- 使用 call 或 apply 可以改变 this 的指向。
7、同步和异步的区别?
同步是一种线性执行的方式,执行的流程不能跨越。一般用于流程性比较强的程序,比如用户登录;
异步是一种并行处理的方式,不必等待一个程序执行完,就可以执行其它任务。在程序中异步处理的结果通常使用回调函数来处理结果。在 JavaScript 中实现异步的方式一般是 Ajax
和 H5 新增的 Web Worker
。
- 同步会阻塞代码执行,而异步不会
- alert是同步,setTimeOut是异步
何时需要异步?
- 在可能发生等待的情况
- 等待过程中不能像alert一样阻塞程序运行
因此,所有的“等待的情况”都需要异步
前端使用异步的场景?
- 定时任务:setTimeOut、setInterval
- 网络请求:ajax请求、动态img加载
- 事件绑定
8、call和apply的区别?
相同点 两个方法产生的作用是一样的,都用来改变当前函数调用的对象;
不同点 调用的参数不同,
foo.call(this, arg1, arg2, arg3) == foo.apply(this, args) == this.foo(arg1, arg2, arg3)
9、eval是做什么的?
把字符串参数解析成JS代码运行,并返回执行的结果。
10、new操作符干了什么?
- 创建一个空对象
var obj = new Object()
;
- 创建一个空对象
- 设置原型链
obj.__proto__ = Function.prototype
;
- 设置原型链
- 让 Function 中的 this 指向 obj,并执行 Function 的函数体
var result = Function.call(obj)
;
- 让 Function 中的 this 指向 obj,并执行 Function 的函数体
- 判断 Function 的返回值类型,如果是值类型,返回 obj,如果是引用类型,就返回引用类型的对象。
11、造成JS内存泄漏的情况?
- 全局变量
- 闭包
- DOM被清空时,事件未被清除
- 子元素存在引用
12、写出下列结果?
console.log(null == NaN); //false
console.log(null == undefined); //true
console.log(null == false); //false
console.log(false == ''); //true
console.log(false == 0); //true
console.log(2 + 1 + '3'); //33
console.log('2' + 1 + 3); //213
console.log(Number(undefined)); //NaN
console.log(Number(NaN)); //NaN
console.log(Number(null)); //0
console.log(Number('')); //0
console.log(Number('123')); //123
console.log(isNaN(23)); //false
console.log(isNaN(NaN)); //true
console.log(isNaN(undefined));//true
console.log(isNaN(null)); //false
console.log(typeof NaN); //number
console.log(typeof '123'); //string
console.log(typeof undefined); //undefined
console.log(typeof 123); //number
console.log(typeof null); //object
console.log(typeof []); //object
console.log(typeof Array); //function
console.log(typeof console.log); //function
console.log(NaN == NaN); //false
console.log(undefined == undefined); //true
13、JS绑定事件的方法?
1)在DOM上直接绑定
<input type="button" value="click me" onclick="hello()" />
<script>
function hello(){
alert('hello')
}
</script>
2)在JavaScript代码中绑定事件
<input type="button" value="click me" id="btn">
<script>
document.getElementById('btn').onclick = function(){
alert('hello');
}
</script>
3)使用事件监听绑定
W3C标准语法:
element.addEventListener(event, function, useCapture)
- event(必选)事件名,支持所有DOM事件;
- function(必选)指定事件触发后执行的函数;
- useCapture(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获;false,冒泡(default);
<input type="button" value="click me" id="btn">
<script>
document
.getElementById('btn')
.addEventListener('click', function() {
alert('hello);
})
</script>
IE标准语法:
element.attachEvent(event, function)
- event(必须)事件类型,需要加“on”,例如“onClick”
- function(必选)指定事件触发后执行的函数
14、JavaScript事件流机制?
1)冒泡型机制
事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发
2)捕获型机制
事件从最不精确的对象(document对象)开始触发,然后到最精确。
3)DOM事件流
同时支持两种事件模型:捕获型事件和冒泡型事件,但是捕获型事件先发生。两种事件都会触发DOM中的所有对象,从document对象开始,也在document对象结束。
事件捕获机制:事件从最上一级标签开始往下查找,直到捕获到事件目标;
事件冒泡机制:事件从事件目标开始,往上冒泡直到页面的最上一级标签。
事件的传播是可以阻止的:
- 在W3C中,使用stopPropagation()方法;
- 在IE下设置cancelBubble = true;
在捕获的事件中stopPropagation()后,后面的冒泡过程也不会发生了
阻止事件的默认行为:
- 在W3C中,使用preventDefault()方法;
- 在IE下设置window.event.returnValue = false
不是所有事件都能冒泡,例如:blur、focus、load、unload等
普通事件和事件绑定的区别?
普通事件的方法不支持添加多个,最下面的事件会覆盖上面的;事件绑定可以添加多个
15、JavaScript实现继承的几种方式?
//父类
function Animal(name) {
this.name = name || 'Animal';
this.sleep = function () {
console.log(this.name + ' sleep');
};
}
Animal.prototype.eat = function (food) {
console.log(this.name + ' eating ' + food)
};
//原型链继承
function Cat() {
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
//构造继承(不能继承原型方法)
function Cat(name) {
Animal.call(this);
this.name = name || 'Tom';
}
//实例继承
function Cat(name) {
const instance = new Animal();
instance.name = name || 'Tom';
return instance;
}
//拷贝继承
function Cat(name) {
const animal = new Animal();
for (let p in animal) {
Cat.prototype[p] = animal[p];
}
Cat.prototype.name = name || 'Tom';
}
16、简要说明对模块化开发的理解?
所谓模块化开发就是封装细节,提供使用接口,彼此之间互不影响,每个模块都是实现某一特定的功能。模块化开发的基础就是函数。
17、Ajax的工作原理?写一个Ajax请求?
Ajax的工作原理相当于在用户和服务器之间加了一个中间件(Ajax引擎),是用户操作与浏览器响应异步化。
const xhr = new XMLHttpRequest();
xhr.open('get', '/api', false);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) { // 0 请求未初始化 1 请求已建立 2 请求已发送 3 请求处理中 4 响应已完成
if (xhr.status == 200) { // 2xx 请求成功 3xx 请求重定向 4xx 客户端错误 5xx 服务端错误
console.log(xhr.responseText)
}
}
};
xhr.send(null);
18、写出两种单例模式的实现?
//自变量
const singleton = {
attr: 1,
method: function () {
return this.attr;
}
};
//构造函数内部判断
function Construct() {
if(Construct.unique !== undefined){
return Construct.unique;
}
this.name = 'name';
this.age = 24;
Construct.unique = this;
}
19、ES6中Array.isArray的代码实现?
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
}
20、window.onload 和 DOMContentLoaded 区别
- window.onload 页面的全部资源加载完才会执行,包括图片、视频等
- DOMContentLoaded DOM渲染完即可执行,此时图片、视频还没有加载完
21、随机打印1-100间的10个数字,去重后取出该10个数字之间的最大值和最小值。
function randomMaxMin() {
const numbers = [...new Set([...new Array(10)].reduce(origin => {
origin.push(Math.ceil(Math.random() * 100));
return origin;
}, []))].sort((a, b) => a - b);
return {min: numbers[0], max: numbers[numbers.length - 1]};
}
22、写一个长度一致的随机数
let random = Math.random() + '0000000000';
random = random.slice(0, 10);
23、写一个能遍历数组和对象的forEach函数
function forEach(obj, fn) {
if (obj instanceof Array) {
obj.forEach((item, index) => fn(index, item));
} else {
Object.keys(obj).forEach(key => fn(key, obj[key]));
}
}
forEach({name: 'pp', age: 20}, (key, value) => {});
forEach([1,2,3], (index, item) => {});
24、写一个闭包的使用场景
function isFirstLoad() {
const _list = [];
return function (id) {
if(_list.indexOf(id) >= 0){
return false;
}else{
_list.push(id);
return true;
}
};
}
const firstLoad = isFirstLoad();
console.log(firstLoad(10)); //true
console.log(firstLoad(10)); //false
console.log(firstLoad(20)); //true
console.log(firstLoad(20)); //false
25、动态创建10个标签,点击弹出对应的序号
for (var i = 0; i < 10; i++) {
(function (i) {
var a = document.createElement('a');
a.innerHTML = 'aaa' + (i + 1) + '</br>';
a.addEventListener('click', function (e) {
e.preventDefault();
alert(i + 1);
});
document.body.appendChild(a);
})(i);
}
最简单的方式用
let
替换var
进行定义。
26、写一个原型继承的案例
function Elem(id) {
this.elem = document.getElementById(id);
}
Elem.prototype.html = function (val) {
const elem = this.elem;
if(val){
elem.innerHTML = val;
return this;
}else{
return elem.innerHTML;
}
};
Elem.prototype.on = function (type, fun) {
const elem = this.elem;
elem.addEventListener(type, fun);
return this;
};
//exec
const div1 = new Elem('app');
div1.html('<p>Hello</p>').on('click', function () {
alert('hello');
}).html('<p>peter</p>');
27、编写一个通用的事件监听函数?
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector;
selector = null;
}
elem.addEventListener(type, function (e) {
if (selector) {
//代理
const target = e.target;
if (target.matches(selector)) {
fn.call(target, e);
}
} else {
//不是代理
fn(e);
}
});
}
const div1 = document.getElementById('div1');
bindEvent(div1, 'click', 'a', function (e) {
e.preventDefault();
console.log(this.innerHTML);
});
const p1 = document.getElementById('p1');
bindEvent(p1, 'click', function () {
console.log(p1.innerHTML);
});
28、js写一个冒泡排序算法
//冒泡排序
function bubble() {
const arr = [3, 1, 2, 4];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
console.log(arr);
}
bubble(); //[1, 2, 3, 4]
29、JS写一个选择排序算法
//选择算法
function selection() {
const arr = [3, 1, 2, 4];
for (let i = 0; i < arr.length - 1; i++) {
let min = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
[arr[i], arr[min]] = [arr[min], arr[i]];
}
console.log(arr);
}
selection(); //[1, 2, 3, 4]
30、JS写一个插入排序算法
//插入排序
function insertion() {
const arr = [3, 1, 2, 4];
for (let i = 1; i < arr.length; i++) {
for (let j = i - 1; j >= 0; j--) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
console.log(arr);
}
insertion(); //[1, 2, 3, 4]
31、写一个二分法的函数,返回给定值的索引
//二分法找索引
function dichotomy(arr, val) {
let start = 0, end = arr.length - 1;
while (start < end) {
let middle = end == 1 ? 0 : Math.floor((start + end + 1) / 2);
if (arr[middle] > val) {
end = middle;
} else if (arr[middle] < val) {
start = middle;
} else {
return middle;
}
}
return -1;
}
console.log(dichotomy([2,3,4,5], 3)); //1
32、现有一个URL字符串“http://www.xxx.com?pn=0”,请写出删除其中的pn属性的js代码,请尽量实现完整,考虑全面。
const arr = url.split('?');
const new_url = arr[0] + '?' + arr[1].split('&')
.reduce((origin, item) => {
(item.split('=')[0] != 'pn') && origin.push(item);
return origin;
}, []).join('&');
console.log(new_url); //http://www.xxx.com
33、写一个函数,计算100以内的质数(只能被1或本身整除的数)。
const calcPrimeNumbers = sum => (
[...new Array(sum)].reduce((origin, item, index) => {
const [number, arr] = [++index, []];
for (let i = 1; i <= number; i++) {
number % i == 0 && arr.push(i);
}
arr.length == 2 && origin.push(number);
return origin;
}, [])
);
console.log(calcPrimeNumbers(100)); //[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 ]
34、用 JS 实现一个无限累加的函数 add
function add() {
let sum = [...arguments].reduce((a, b) => a + b);
const foo = function () {
sum += [...arguments].reduce((a, b) => a + b);
return foo;
};
foo.toString = () => sum;
return foo;
}
console.log(add(1)(2)(3)(4)); // 10
console.log(add(1,1)(2,2)(3,3)(4,4)); // 20
35、手动实现一个sleep函数?
function sleep(time) {
const start = Date.now();
while (true) {
if(Date.now() - time > start)
break;
}
console.log('休息了' + time / 1000 + '秒')
}
sleep(3000); //休息了3秒
36、普通函数和箭头函数的区别?
- 箭头函数是匿名函数,不能作为构造函数,不能使用 new;
- 箭头函数不绑定 arguments,取而代之用rest参数(...)解决;
- 箭头函数不绑定 this,会捕获其所在的上下文的 this 值,作为自己的 this 值;
- 箭头函数没有原型属性。
37、如何发送携带cookie的跨域请求?
设置 withCredentials = true;
38、根据id快速查找对应的元素
const tree = {
id: 'root',
children: [
{ id: 1, children: [] },
{ id: 2, children: [] },
{ id: 3, children: [] },
{
id: 4,
children: [
{ id: 5, children: [] },
]
},
]
};
function find(id, node = tree) {
if (node.id == id) {
return node.children;
}
let target;
node.children.forEach(child => {
if (child.id == id) {
target = child.children;
} else {
find(child.id, child);
}
});
return target;
}
console.log(find(1)); // []
39、实现对数组进行乱序
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var sign = 1;
arr.sort((a, b) => {
sign = Math.random() > 0.5 ? 1 : -1;
return (a - b) * sign;
});
console.log(arr);
40、计算长度为100的数组前10个元素之和。
var arr = [...new Array(100)].map((item, i) => i + 1);
var result = arr.slice(0, 10).reduce((pre, current) => pre + current);
console.log(result); // 55
41、手动实现一个bind函数
Function.prototype.myBind = function (oThis) {
let args = [...arguments].slice(1);
const context = this;
const bound = function () {
args = [...args, ...arguments];
return context.apply(this instanceof F && oThis ? this : oThis, args);
};
const F = function () {
};
F.prototype = context.prototype;
bound.prototype = new F();
return bound;
};
function read(name, time, book) {
console.log(`${name} is reading ${book} at ${time}`)
}
const tomRead = read.myBind(this, 'Tom', 'morning');
tomRead('三体'); // Tom is reading 三体 at morning
42、手动实现一个深拷贝
function copy(obj) {
const result = obj instanceof Array ? [] : {};
for (let item in obj) {
if (typeof obj[item] == 'object') {
result[item] = copy(obj[item]);
} else {
result[item] = obj[item];
}
}
return result;
}
6、HTTP状态码分别表示什么?
2xx 成功
- 200 OK,表示从客户端发来的请求在服务器端被正确处理
- 204 No content,表示请求成功,但响应报文不含实体的主体部分
- 205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
- 206 Partial Content,进行范围请求
3xx 重定向
- 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
- 302 found,临时性重定向,表示资源临时被分配了新的 URL
- 303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源
- 304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
- 307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
4xx 客户端错误
- 400 bad request,请求报文存在语法错误
- 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
- 403 forbidden,表示对请求资源的访问被服务器拒绝
- 404 not found,表示在服务器上没有找到请求的资源
5xx 服务端错误
- 500 internal sever error,表示服务器端在执行请求时发生了错误
- 501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
- 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
details
- 100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分
- 101 Switching Protocols 服务器将遵从客户的请求转换到另外一种协议
- 200 OK 一切正常,对GET和POST请求的应答文档跟在后面
- 201 Created 服务器已经创建了文档,Location头给出了它的URL。
- 202 Accepted 已经接受请求,但处理尚未完成。
- 203 Non-Authoritative Information 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝
- 204 No Content 没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的
- 205 Reset Content 没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容
- 206 Partial Content 客户发送了一个带有Range头的GET请求,服务器完成了它
- 300 Multiple Choices 客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在Location应答头指明。
- 301 Moved Permanently 客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。
- 302 Found 类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。
- 303 See Other 类似于301/302,不同之处在于,如果原来的请求是POST,Location头指定的重定向目标文档应该通过GET提取
- 304 Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
- 305 Use Proxy 客户请求的文档应该通过Location头所指明的代理服务器提取
- 307 Temporary Redirect和302(Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是 POST,即使它实际上只能在POST请求的应答是303时才能重定向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码: 当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只能跟随对GET请求的重定向。
- 400 Bad Request 请求出现语法错误。
- 401 Unauthorized 客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的Authorization头后再次发出请求。
- 403 Forbidden 资源不可用。
- 404 Not Found 无法找到指定位置的资源
- 405 Method Not Allowed 请求方法(GET、POST、HEAD、Delete、PUT、TRACE等)对指定的资源不适用。
-
406 Not Acceptable
指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容 -
407 Proxy Authentication Required
类似于401,表示客户必须先经过代理服务器的授权。 - 408 Request Timeout 在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。
- 409 Conflict 通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。
- 410 Gone 所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。
- 411 Length Required 服务器不能处理请求,除非客户发送一个Content-Length头。
- 412 Precondition Failed 请求头中指定的一些前提条件失败
- 413 Request Entity Too Large 目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个Retry-After头
- 414 Request URI Too Long URI太长
- 416 Requested Range Not Satisfiable 服务器不能满足客户在请求中指定的Range头
- 500 Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求
- 501 Not Implemented 服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求
- 502 Bad Gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答
- 503 Service Unavailable 服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头
- 504 Gateway Timeout 由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答
- 505 HTTP Version Not Supported 服务器不支持请求中所指明的HTTP版本