4.行内元素和块级元素的区别?
格式上:默认情况下,行内元素不会以新行开始,而块级元素会
内容上:默认情况下,行内元素只能包含文本和其他行内元素,而块级元素可以包含文本和其他行内元素与块级元素
行内元素和块级元素属性不同,行内元素设置width/height无效
5.空元素?
空元素是指中间没有内容的标签,即单标签
...
6.页面导入样式时,使用@import 和 link标签 有什么区别?
1.@import 是css的语法规则,只有导入样式表的作用;而link既可以导入样式表,还可以设置rel等属性引入网站图表等
2.link标签引入的css被同时加载;而用@import 引入的css则需要等到页面加载完毕之后加载
3.link标签可以被js脚本动态插入改变样式,而@imoprt 不可以
7.浏览器内核/引擎?
浏览器的内核引擎分为渲染引擎和JS引擎,
渲染引擎的功能就是渲染,即在浏览器中展示所请求的内容,默认情况下,渲染引擎可以渲染xml,html,图片等,还可以借助插件渲染pdf
JS引擎的功能就是解析执行javascript脚本,
8.常见的浏览器内核?
IE Trident
Chrome Blink
Firefox Gecko
Safari Webkit
9.浏览器渲染过程中遇到js文件怎么处理?
在构建DOM时,HTML若遇到了javascript脚本,则它会暂停对文档的解析,通过JS引擎解析运行javascript脚本,等待js加载完毕,才会从中断的地方继续加载文档
10.defer 和 async 的作用和区别?
JS脚本没有defer和async属性的话,浏览器会立即加载运行javascript
defer属性表示延迟执行引入的javascript,即这段代码在加载时HTML并未停止解析,这两个过程是并行的
async属性代表异步执行javascript,与defer的区别在于,如果已经加载好,就会开始执行,也就是说它的执行仍然会阻塞文档的解析,只是它的加载过程中不会阻塞,多个脚本的执行顺序无法保证
11.渲染页面时常见的不良影响?
样式闪烁问题: CSS文件大加载缓慢或者放在body底部导致
白屏:JS脚本放在head头部加载
12.重绘 和 回流 ?
重绘:当渲染树中一些元素需要更新属性时,而这些属性只影响元素的外观,风格,而不会影响布局的操作,比如 background color 等称为重绘;
回流:当渲染树中的一部分或全部因为元素的尺寸 布局 隐藏等改变而需要重新构建的操作,会影响到布局的操作称为回流。
添加/删除可见的DOM元素
元素尺寸改变 (margin padding border width height)
内容变化,(input输入框中输入文字)
浏览器窗口尺寸改变 -resize事件
。。。
回流必引起重绘,重绘不一定会引起回流。
13.如何减少回流?
使用transfrom代替top
不要使用table布局,可能很小的改动都会造成整个table的回流
不要一条一条的修改DOM样式,与其这样,还不如事先定义好css的class,然后修改DOM的className
14.HTML5 有哪些新特性?
1.H5语义化标签
2.表单控件:date time email search url
2.Canvas画布
3.Video Audio 音视频
4.本地存储 localStorage
5.地理定位 geolocation
6.离线存储 appcache
7.新的文档属性 document.visibilityState
8.新的技术 websocket
15.如何处理HTML5新标签的兼容性问题?
通过现成第三方库 html5shiv.js / 通过document.createElement()方法创建标签
16. b和strong 与 i和em的区别?
b和strong都是粗体,i和em都是斜体
strong和em具有语义化,强调文本
17.前端需要注意哪些SEO优化?
1.合理的title,description,keyword,title值强调重点即可,description把内容高度概括,keyword列举出几个关键字即可
2.语义化的HTML代码,符合W3C规范
3.重要内容html代码放在最前面,保证内容肯定被抓取
4.重要的内容不要用js输出,爬虫不会执行js获取内容
5.非装饰性的图片必须用alt
6.提高网站速度:网站速度是搜索引擎排序的一个重要指标
18.浏览器的存储方式及区别?
浏览器的存储方式有cookie sessionStorage localStorage
cookie:最多能存储4k数据,生成时间由expire属性决定,只能被同源的页面访问共享
sessionStorage:会话存储,能够存储5M大小或更大的数据,随着浏览器的关闭而释放数据,只能被同一个窗口的同源页面所共享访问
localStorage:本地存储,能够存储5M大小或更大的数据,不会随着浏览器的关闭而清除数据,除非手动清除,否则会一直存在浏览器中,只能被同源的页面访问共享
19.Lable标签的作用是什么? 用法?
label标签用来定义表单控件间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上
20.如何实现浏览器内多个标签页之间的通信?
1.可以通过websocket协议,因为websocket协议可以实现服务器推送,所以服务器就可以用来当做这个中介者,标签页通过向服务器发送数据,然后服务器向其他标签页推送转发
2.使用localStorage本地存储方式,可以在一个标签页对localStorage变化事件进行监听,然后当另一个标签页修改数据的时候,就可以通过这个监听事件来获取到数据
21.webSocket如何解决低版本浏览器兼容性问题?
1.Adobe Flash Socket
2.基于长轮询的XHR请求(XmlHttpRequest ajax)
22.页面可见性(Page Visibility API) 可以有哪些用途?
这个API的作用在于,通过监听网页的可见性,可以预判卸载网页,还可以用来节省资源,比如:一旦用户不看当前网页,就可以停止对当前网页的轮询,停止网页的动画,音视频等等
23.实现不用border画出1px高度的线,兼容浏览器标准模式和怪异模式
{
overflow:hidden;
height:1px;
background-color:red;
}
24.title和h1的区别?
title属性没有明确意义只是表示标题,h1则表示层次明确的标题,对页面信息的抓取也有很大的影响
25.img的title和alt的区别?
title通常是鼠标滑入当前元素时所展示的信息,而alt是img的特有属性,为图片无法展示时显示的信息,搜索引擎会重点分析alt属性
26.Canvas和svg的区别?
Canvas是一种通过JavaScript绘制2D图形的方法,以像素的形式描绘,所以放缩时会导致锯齿失真的情况
SVG是一种通过XML绘制的2D图形的语言,当SVG缩放时并不会失真
27.网页验证码的作用?
1.区分用户是计算机还是人的公共全自动程序,可以防止恶意破解密码,刷票,论坛灌水
2.有效防止黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试
28.attribute和property的区别?
如上述div元素,可通过 document.getElementById('dv').getAttribute('id') 获取id的值 也可以通过document.getElementById('dv').id 的方式
前者称为attribute ,后者称为property
只要是HTML标签内定义的都是attribute,两者同步,Attribute值是字符串类型
Property属性则可以看做是DOM对象的键值对,用点操作符对它们进行操作,非自定义attribute,如id、class、titile等,都会有对应的property映射。就算没有在标签中出现都会有空值
实际编程中,基本的DOM操作都是使用property的点操作符
只有两种情况不得不使用attribute,
1.自定义Attribute,因为它不能同步到DOM property (比如上面的div元素的data-id属性)
2.访问内置的HTML标签的Attribute,这些attribute不能从property上同步过来,(比如input标签的value值)
29.用于预格式化文本格式的标签是?
保持文本原有的格式
30.head标签中必不可少的是?
为头部标签,可以在head标签中使用
63.什么是cookie隔离? 或者说 资源请求的时候不带上cookie怎么做? cookie隔离是指将静态资源文件存放在非主域名下,这样请求静态资源时就不会带着cookie 64.什么是css预处理器/后处理器? css预处理器定义了一种新的语言,为css提供了一些编程的特性,然后再编译成正常的css文件,如less ,sass 等 css后处理器是对css进行处理,并最终生成css的预处理器,如 postcss 65.画一条0.5px的线 66.transition和animation的区别? transition 关注的是css属性的变化,而animation作用于元素本身并不是样式属性,可以使用关键帧的概念,实现更自由的动画 67.什么是首选最小宽度? 首选最小宽度指的是元素最适合的最小宽度,中文最小宽度为每个汉字的宽度,英文最小宽度由特定的连续的英文字符决定, 所以如果想让英文和中文一样,每一个字符都是用最小宽度,则可以设置css { word-break:break-all; } 68.为什么height:100%;会无效? 对于普通文档流中的元素,百分比高度要想起作用,其父元素必须有一个可以生效的高度值。 69.什么是替换元素? 通过修改某个属性值呈现的内容就可以被替换的元素称为替换元素。如:、 70.如何实现单行、多行文本溢出的省略(...) 单行溢出: p{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } 多行溢出: p{ position:relative; line-height:1.5em; height:3em; 两行省略,3/1.5=2 overflow:hidden; word-break:break-all; } p::after{ content:'...'; position:absolute; bottom:0; right:0; background-color:#fff; } 71.常见的元素隐藏方式? 1.display:none; 2.opacity:0; 3.visibility:hidden; 4.{ position:absolute;left:-9999px;top:-9999px; } 5.{ position:absolute;z-index:-999px; } 6.{ width:0;height:0; } 7.transform:scale(0,0) 72.css实现上下固定,中间自适应布局? 1.绝对定位方式: 2.使用flex布局: 73.css实现两栏布局? 1.浮动实现 2.绝对定位 3.flex布局 74.三栏布局? 1.左右浮动宽度200px;中间设置margin:0 200px;需要注意的是中间的元素需要放在最底下 2.父元素相对定位,左右元素绝对定位在两侧设置宽度,中间margin:0 200px; 3.flex布局,父元素display:flex;左右两元素设置宽度,中间元素flex:1; 75.js中的数据类型? 基本数据类型:Number String Boolean undefined null 引用数据类型:Object Array Function 76.js中有哪些内置对象? JS中的内置对象主要是指程序执行前存在全局作用域里由js定义的一些全局值属性、函数和用来实例化其他对象的构造函数对象。 一般我们经常用到的全局值属性:NaN、undefined,全局函数如:parseInt(),parseFloat(),用来实例化对象的构造函数如:Date,Object,Math 77.undefined与undeclared的区别? 已在作用域下声明但还没赋值的变量是undefined,还没有在作用域下声明过的变量是undeclared。 对于undeclared变量的引用,浏览器会报引用错误,但是我们可以通过typeof的安全机制来避免这种报错,因为undeclared的变量typeof会返回undefined 78.undefined和null的区别? 首先undefined和null都是基本数据类型,undefined指的是变量已声明但未赋值,null代表的含义为空对象 79.JavaScript原型 原型链 ? 个人理解:原型就是一个属性,这个属性同时也是一个对象,构造函数中有一个属性prototype就是原型,原型的作用:共享数据,节省内存空间,实现继承 原型链是指实例对象和原型对象是通过__proto__原型来联系的,这种关系叫做原型链 80.在js中不同进制数表示方式? 二进制:0b 以0b开头 八进制:0o 以0o开头 十进制: 十六进制:0x00 以0x开头 81.typeof NaN 的结果是什么? 结果为number。 NaN指的是‘不是一个数字’,用于指出数字类型中的错误情况,即执行数学运算没有成功 NaN是一个特殊值,它和自身不相等,是唯一一个非自反的值;即 NaN != NaN 为true 82.解析字符串中的数字parseInt() 和 将字符串强制类型转换为数字Number() 的返回结果都是数字,他们有什么区别? 解析字符串parseInt()中含有非数字字符,解析从左到右解析,解析到非数字字符时即会停止 强制类型转换Number()不允许出现非数字字符,否则会失败返回NaN 83.什么情况下会发生布尔值的隐式强制类型转换? 条件判断表达式中会发生布尔值的隐式强制类型转换 比如:1. if( .. ){} 2. ..? '':'' 3.逻辑与&&、逻辑或|| 4.do while(..) 等等 84.如何将浮点数左边的数每三位添加一个逗号(千位分隔符)? 如 12000000.11转化为 12,000,000.11 包含整数? 85.JavaScript创建对象的几种方式? 1.工厂模式(解决了创建多个相似对象时,代码的复用问题;没有解决对象识别的问题,即不知道对象的类型) 2.构造函数模式(解决了工厂模式对象识别问题;没创建一个对象都会创建一个saiName函数的实例做相同的事,造成内存的浪费) 3.原型模式 4.构造函数模式+原型模式 组合 86.JavaScript实现继承的几种方式? 1.原型链继承 2.借用构造函数继承 3.组合继承 4.寄生式继承 5.寄生式组合继承 (引用类型最理想的继承范式) 87.JavaScript作用域链? 作用域链的作用是保证执行环境有权访问的所有变量和函数的有效访问,通过作用域链,我们可以访问到外层环境的变量和函数。 88.This的理解? this是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。在实际开发中,this的指向可以通过四种调用模式来判断 1.函数调用模式,当一个函数直接作为函数来调用时,这个this指的是window(全局对象) 2.方法调用模式,当一个函数以一个对象的方法来调用时,这个this指的是这个对象 3.构造器调用模式,当一个函数用new的方式调用时,函数执行前会新创建一个对象,this指向这个新创建的对象 4.apply、call、bind调用模式,这三个方法都可以显示的指定调用函数的this指向 89.写一个通用事件函数(封装 绑定事件、解绑事件、获取事件目标、获取event、阻止冒泡、取消默认行为)? 绑定事件: 解绑事件: 获取事件目标: 获取event 阻止冒泡: 取消默认行为: 90.三种事件模型是什么? 事件处理机制 第一种事件模型(原始事件模型):通过onclick,on+'事件类型'的形式绑定事件,只能绑定一个相同事件,再次绑定将会覆盖之前的事件 第二种事件模型(IE事件模型): 通过attachEvent绑定事件,只支持冒泡,所以事件有两个阶段,目标阶段和冒泡阶段,事件从目标元素冒泡到document,并且一次检查各个节点是否绑定了事件,如果有则执行 第三种事件模型:通过addEventListener绑定事件,有三个阶段,捕获阶段、目标阶段、冒泡阶段。捕获阶段:事件从外向内执行document->ele;冒泡阶段:事件从内向外执行ele->document;默认为冒泡(false) 91.事件委托是什么? 事件委托的本质上利用了浏览器事件冒泡的机制,因为事件在冒泡的过程中会上传到父节点,并且父节点可以通过事件对象获取到目标节点, 因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方式成为事件委托。 92. ["1","2","3"].map(parseInt) 答案是什么? map() 接收三个参数 item,index,arr (当前遍历项,当前索引,当前数组) parseInt() 接受两个参数 str,radix (要被解析的字符串,要解析的数字的基数) 因为map()遍历第三个参数不需要,所以map之后的数组为[ parseInt(1,0), parseInt(2,1), parseInt(3,2) ] 因为parseInt()第二个参数的值的取值范围在2~36之间且包含0,并且第一个参数的值的首位必须小于第二个参数,否则为NaN 所以最终的结果就是 [1,NaN,NaN] 93.闭包? 闭包是指有权访问另一个函数作用域中变量的函数, 闭包的作用: 1.函数外部能够访问到函数内部的变量。通过使用闭包,在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量 2.使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收 94.javascript代码中的"use strict";是什么意思?使用它区别是什么? "use strict" 指的是一种严格运行模式,在这种模式对js的使用添加了一些限制,比如说禁止this指向全局变量,禁止使用with语句等。 95.怎么判断一个数据属于某种数据类型? (如何判断一个对象是否属于某个类) 96.JavaScript中,哪个函数执行对象查找时永远不会去查找原型? Object.hasOwnProperty() : 用来检测一个对象是否含有特定的自身属性 97.对于JSON的了解? JSON是一种基于文本的轻量级数据交换格式,它可以被任何的编程语言读取和作为数据格式来传递。 在js中,有两个操作json的方法,JSON.stringify():通过一个符合json格式的数据结构,将其转换为一个json字符串 JSON.parse():将一个符合json格式的字符串转换成一个js数据结构,如果不符合json格式的字符串则会报错。 98.JS延迟加载的方式有哪些? 1.放在body标签底部 2.
141.let和const的注意点? let: 1.不存在变量声明提升 2.存在暂时性死区(只要块级作用域内存在let命令,它所声明的变量就绑定了这个区域,不再受外界影响) 3.不允许重复声明 const: 1.声明常量必须赋值,否则报错 2.也存在暂时性死区(只能在声明的位置后面使用。) 3.不允许重复声明,不存在声明提升 4.常量不允许被修改,(只针对于基本数据类型,引用数据类型除外) 142.Set和WeakSet? ES6提供了新的数据结构Set,它类似于数组,但是成员的值都是唯一的,没有重复的值,(一般用来做数组去重)。 WeakSet和Set类似,也是不重复值得集合,但是WeakSet的成员只能是对象,不能是其他类型的值。WeakSet不能遍历 WeakSet的对象都是弱引用,因此适合临时存放一组对象以及存放跟对象绑定的信息,只要这些对象在外部消失,它在WeakSet的引用也会消失。 143.Map和WeakMap? Map数据结构类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值都可以当作键。 WeakMap类似于Map,也是键值对的集合,但是键只能是对象(null除外),不接受其他类型的值作为键名。 WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。 144.什么是Proxy? Proxy用来修改某些操作的默认行为,等同于在语言层面上进行修改,所以属于一种“元编程”,即对编程语言进行编程。 Proxy可以理解成,在目标对象之前架设一层拦截,外界对这个对象的访问都必须先通过这层拦截,因此提供了一层机制, 可以对外界的访问进行过滤和改写。 145.什么是Promise对象? 什么是Promise/A+规范 ? Promise对象是异步编程的一种解决方案;Promise/A+规范是javascript Promise的标准,规定了一个Promise所必须具有的特性。 Promise是一个构造函数,接收一个函数作为参数,返回一个Promise实例。一个Promise实例有三种状态,分别是:pending、resolved、rejected, 分别代表了进行中、已成功、已失败。实例的状态只能由pending转变为resolved或者rejected状态,并且状态一经改变,就无法在被更改了。 状态的改变是由resolve()和reject()函数来实现的。我们可以在异步操作结束后调用这两个函数改变Promise实例的状态,它的原型上定义了一个then方法, 使用这个then方法可以为两个状态的改变注册回调函数,这个回调函数属于微任务,会在本轮事件循环的末尾进行。 146.手写一个Promise 147.怎么做JS代码的error统计? 通过window.onerror事件进行统计,需要放在所有js脚本前执行 148.Vue的生命周期是什么? 有哪些阶段? Vue的生命周期指的是组件从创建到销毁的一系列过程,称之为Vue生命周期。有8个阶段(创建前,创建后,加载前,加载后,更新前,更新后,销毁前,销毁后) 每个阶段都对应了一个生命周期的钩子函数。 beforeCreate 组件创建前 created 组件已创建(此时已经可以拿到data中的数据了) beforeMount 虚拟DOM渲染前 mounted 虚拟DOM已渲染 beforeUpdate 数据更新时调用(适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器) updated 数据更改导致DOM重新渲染后调用(一般不在这里做什么操作而是用watch或computed) beforeDestroy 实例销毁前(一般会在这里销毁定时器,解绑全局事件) destroyed 实例销毁后,Vue实例中所有的东西都会被移除 处于 keep-alive 缓存的组件还有两个生命周期并且不会被销毁而是执行了这两个生命周期,activated和deactivated,分别代表 缓存的组件被激活、缓存的组件被停用 149.Vue组件间的传递方式? 父子组件间通信: 1.子组件通过props属性来接收父组件的数据;然后父组件在子组件上注册监听事件,子组件通过$emit触发事件来向父组件发送数据 2.通过ref属性给子组件设置一个名字,父组件通过$refs组件名来获得子组件;子组件可以通过$parent来获得父组件 3.使用provider/inject,在父组件中通过provider提供变量,在子组件中通过inject来将变量注入到组件中。无论子组件有多深,只要调用了inject就可以注入provider中的数据 兄弟组件间通信: 1.通过EventBus的方式,本质就是创建一个空的Vue实例来作为消息传递的对象,通过在这个实例上监听$on和触发$emit事件,来实现消息的传递 2.通过$parent.$refs来获取兄弟组件进行通信 任意组件间通信: 业务不复杂的情况下也可以使用EventBus的方式,不然就用Vuex 150.computed和watch的差异? 1.computed是计算一个新的属性,并将该属性挂载到Vue实例上;而watch是监听已经存在并挂载到Vue实例上的数据,所以用watch同样可以监听computed计算属性的变化 2.computed本质是一个惰性的观察者,具有缓存性,只有当依赖发生变化后,第一次访问computed属性才会计算新的值;而watch则是当数据发生变化便会调用执行函数,methods也是 3.从使用场景上说,computed适用于一个数据被多个数据影响,watch适用于一个数据影响多个数据 151.vue-router中导航钩子函数(导航守卫) 全局守卫:beforeEach 和 afterEach beforeEach((to,from,next)=>{})前置守卫: 接收三个参数,to:要进入的路由对象,from:要离开的路由对象,next是一个必须要执行的函数, 该函数(next)如果不传参数,那就执行下一个钩子函数,如果传入false,则终止跳转,如果传入一个路径,则导航到对应的路由,如果传入error,则导航终止,error传入错误的监听函数。 afterEach((to,from)=>{}) 后置守卫: 和前置守卫不同的就是不用传入next 路由独享守卫:beforeEnter 路由配置上进行定义,和beforeEach的方法参数是一样的 组件内守卫:beforeRouteEnter beforeRouteUpdate beforeRouteLeave 组件内进行定义,和beforeEach的方法参数是一样的 152. $route 和 $router 的区别? $route:是路由信息对象,包括path、params、query、hash、name等路由信息参数, $router:是路由实例对象包括了路由的跳转方法,钩子函数等(push() replace() go() back() ...) 153.Vue常用的修饰符? 事件修饰符: .stop 阻止冒泡 .prevent 取消默认事件 .capture 使用事件捕获机制 .once 只执行一次 .self 操作当前元素才执行 .native 监听组件根元素事件 v-model修饰符: .trim 清空两端空字符 .number 转换成数字类型 .lazy 延迟更新,让数据失去焦点时更新 154.Vue中key的作用? key的作用可以分为两种情况,第一种是v-if中使用key,第二种是v-for中使用key v-if:由于Vue会尽可能高效的渲染元素,通常是复用已有元素而不是从头开始渲染。因此,当我们使用v-if来实现元素切换的时候,如果切换前后含有相同类型的元素, 那么这个元素就会被复用。如果是相同的input元素,那么切换前后用户的输入不会被清除掉,可以使用key来标识一个唯一元素,这种情况下,使用key的元素不会被复用。 这个时候key的作用是用来标识一个独立的元素。 v-for:用v-for更新已渲染过的元素列表时,它默认使用“就地复用”的策略。如果数据项的顺序发生了改变,Vue不会移动DOM元素来匹配数据项的顺序,而是简单复用此处的每个元素, 因此通过为每一个列表项提供一个key值,以便跟踪元素所在的位置,从而高效的实现复用。这个key的作用是为了高效的更新渲染虚拟DOM 155.keep-alive组件有什么作用? 具有缓存组件的作用:如果你需要在组件切换的时候,保存一些组件的状态防止多次渲染,就可以使用keep-alive组件包裹需要保存的组件。 156.Vue中mixin和mixins的区别? minxin:用于全局混入,会影响到每个组件实例。 minxins:最常使用的扩展组件的方式了,如果多个组件中有相同的业务逻辑,就可以将这些逻辑剥离出来,通过minxins混入代码,比如返回上一个页面,上拉下拉等操作, 需要注意的是minxins混入的钩子函数会先于组件内的钩子函数执行,并且在遇到同名选项时也会有选择性的进行合并 157.开发中几种常用的Content-Type ? 1. application/x-www-form-urlencoded 原生form表单 2. multipart/form-data 常见post提交方式 文件上传 3. application/json JSON字符串 4. text/xml 用来提交xml格式的数据 158.如何封装一个javascript的类型判断函数? 159.如何判断一个对象是否为空对象? Object.keys(o).length === 0 160.手写一个jsonp? 161.手写一个观察者模式? 162.js命名规则? 开头字符必须是字母、下划线或 $符号, 余下的字符可以是下划线、$、或任意字母或数字字符 163.Object.assign() Object.assign(target,source1,source2...) 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象 (浅拷贝) 164.Math.ceil() 和 Math.floor() Math.ceil():向上取整 Math.floor():向下取整 165.如何查找一篇英文文章出现频率最高的单词? 166. 算法知识总结 (1).冒泡排序 (2).选择排序 (3).插入排序 (4).希尔排序 (5).归并排序 (6).快速排序 (7).推排序 (8).基数排序 动态规划 爬楼梯问题->(有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶。要求用程序来求出一共有多少种走法?) 167.js实现一个函数,完成超过范围的两个大整数相加功能 168.JS如何实现数组扁平化(将一个多维数组变成一个一维数组) [1, [2, 3, [4, 5]]] ------> [1, 2, 3, 4, 5] 169.JS实现数组去重? 170.求数组的最大值 和 最小值? 171.如何求两个数的最大公约数? 最小公倍数? 最大公约数: 用大的数去除以小的那个数,然后再用小的数去除以的得到的余数,一直这样递归下去,直到余数为 0 时,最后的被除数就是两个数的最大公约数 最小公倍数:将两个数相乘,然后除以它们的最大公约数 172.判断一个字符串是否为回文字符串? 173.状态码? 1xx : 代表服务器接收到请求 2xx : 代表成功 200:成功 3xx : 代表重定向 301:永久性重定向 302:临时性重定向 304:所请求的资源未修改 4xx : 代表客户端错误 400:客户端请求语法错误 404:请求资源不存在 5xx : 代表服务器端错误 500:服务器内部错误 174.post 和 get 请求的区别? post和get都是http请求的两种方法 get请求一般用于不会对服务器资源产生影响的场景,浏览器一般会对get请求缓存,get请求的url会被保存在历史记录中,不太安全,并且浏览器对url有一个长度的限制,所以会影响get请求发送数据时的长度。 post请求一般用于会对服务器资源产出影响的场景,浏览器很少会对post请求缓存,post请求相对安全,请求参数支持更多的数据类型。 175.当你在浏览器中输入Google.com并且按下回车之后发生了什么? 1.首先会对url进行解析,分析所需要使用的传输协议和请求的资源路径,如果输入的url中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。 如果没有问题,浏览器会检测url中是否出现了非法字符,如果存在非法字符,则对非法字符进行转义后再进行下一个过程 2.浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并没有失效,那么就直接使用,否则向服务器发起新的请求。 3.下面是TCP建立连接的三次握手的过程,首先是客户端向服务器发送一个连接请求,服务端接收到请求后向客户端发送一个应答,客户端收到应答后也向服务器发送了一个应答,此时双方的连接就建立起来了。 4.当页面请求发送到服务器端后,服务器会返回一个html文件作为响应,浏览器接收到响应后,开始对html进行解析,开始页面的渲染过程。 5.浏览器首先会对html文件构建DOM树,根据解析到的css构建CSSOM树,如果遇到script标签,则判断是否含有defer或async属性,要不然script脚本的加载和执行会造成页面渲染的阻塞, 当DOM树和CSSOM树建立好后,根据它们来建构渲染树,渲染树构建好后,会根据渲染树来进行布局,布局完成后,浏览器对页面进行绘制,这个时候整个页面就出来了 176.http中的OPTIONS请求方法有什么作用? OPTIONS会请求服务器返回该资源所支持的所有http请求方法,该方法会用*来代替资源名称向服务器发送OPTIONS请求,可以测试服务器功能是否正常。 JS的XMLHTTPRequest对象进行CORS跨域资源共享时,对于复杂请求,就是使用OPTIONS方法发送预请求,以判断是否有对指定资源的访问权限 177.怎么实现多个网站之间共享登录状态? 在多个网站之间共享登录状态指的就是单点登录。多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 我认为单点登录可以这样来实现,首先将用户信息的验证中心独立出来,作为一个单独的认证中心,该认证中心的作用是判断客户端发送的账号密码的正确性, 然后向客户端返回对应的用户信息,并且返回一个由服务器端秘钥加密的登录信息的 token 给客户端,该token 具有一定的有效时限。 当一个应用系统跳转到另一个应用系统时,通过 url 参数的方式来传递 token,然后转移到的应用站点发送给认证中心,认证中心对 token 进行解密后验证, 如果用户信息没有失效,则向客户端返回对应的用户信息,如果失效了则将页面重定向会单点登录页面。 {
width:100%;
height:1px;
background-color:red;
transform:scaleY(.5);
}
header,footer{
position:absolute;
height:100px;
left:0;
right:0;
}
header{
top:0;
}
main{
position:absolute;
top:100px;
bottom:100px;
}
footer{
bottom:0
}
body{
display:flex;
flex-direction:column;
height:100vh;
}
header,footer{
height:100px;
background-color:red
}
main{
flex-grow:1;
background-color:green;
}
.left{
float:left;
width:200px;
}
.right{
margin-left:200px;
width:auto;
}
.left{
position:absolute;
left:0;
width:200px;
}
.right{
position:absolute;
left:200px;
}
或
.right{
margin-right:200px;
}
box{
display:flex;
}
.left{
width:200px;
}
.right{
flex:1
}
function format(number){
var number = number + ''
if(number.indexOf('.')!=-1){
return number.replace(/(?!^)(?=(\d{3})+\.)/g, ",");
}else{
return number.replace(/\d{1,3}(?=(\d{3})+$)/g,"$&,")
}
}
function createPerson(name,age){
var o = new Object();
o.name = name;
o.age = age;
o.saiName = function(){ alert(o.name) }
return o
}
var person1 = createPerson('zs',18)
var person2 = createPerson('ls',16)
function createPerson(name.age){
this.name = name;
this.age = age;
this.saiName = function(){ alert(this.name) }
return this
}
var person1 = new createPerson('zs',18)
var person2 = new createPerson('ls',16)
function Person(){}
Person.prototype.name = 'zs'
Person.prototype.age = 18
Person.prototype.saiName = function(){ alert(this.name) }
var person1 = new Person()
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype = {
constructor: Person,
sayName: function(){
alert(this.name);
}
}
var person1 = new createPerson("james",9,"student");
var person2 = new createPerson("kobe",9,"student");
function SuperType(){
this.colors = ['red','green','blue']
}
function SubType(){}
SubType.prototype = new SuperType()
var subtype1 = new SubType();
console.log(subtype1.colors.push('white')) // 4 ['red','green','blue','white']
var subtype2 = new SubType();
console.log(subtype2.colors) // ['red','green','blue','white']
function SuperType(){
this.colors = ['red','green','blue']
}
function SubType(){
SuperType().call(this)
}
var instance1 = new SubType()
instance1.colors.push('yellow')
console.log(instance1.colors) // ['red','green','blue','yellow']
var instance2 = new SubType()
console.log(instance2.colors) // ['red','green','blue']
function SuperType(name){
this.name = name
this.colors = ['red','green','blue']
}
SuperType.prototype.sayName = function(){ console.log(this.name) }
function SubType(name,age){
SuperType.call(this,name)
this.age = age
}
//继承方法
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
var instance1 = new SubType("james",9);
instance1.colors.push("black");
console.log(instance1.colors); //"red,green,blue,black"
instance1.sayName(); // "james"
var instance2 = new SubType("kobe",10);
console.log(instance2.colors); //"red,green"blue,
instance2.sayName(); // "kobe"
function createPerson(person){
var clone = object(person) // 通过调用函数创建新对象
clone.saiHi = function(){ // 某种方式增强这个对象
console.log(‘hi’)
}
return clone // 返回这个对象
}
var person1 = createPerson({name:'zs'})
person1.saiHi() // hi
function inheritPrototype(subType, superType) {
//1.创建了超类(父类)原型的(副本)浅复制
var prototype = Object.create(superType.prototype);
// 2.修正子类原型的构造函数属性
// constructor属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数
// prototype.constructor 未修改前指向的 superType,为了弥补因重写原型而失去的默认constructor属性。
prototype.constructor = subType;
// 3.将子类的原型替换为超类(父类)原型的(副本)浅复制
subType.prototype = prototype;
}
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function () {
alert(this.name);
};
function SubType(name, age) {
//构造函数式继承--子类构造函数中执行父类构造函数
SuperType.call(this, name);
this.age = age;
}
// 核心:因为是对父类原型的复制,所以不包含父类的构造函数,也就不会调用两次父类的构造函数造成浪费
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function () {
alert(this.age);
}
var instance = new SubType("lichonglou");
console.log(instance.name)
function addEvent(ele,eventType,fun){
if(ele.addEventListener){
ele.addEventListener(eventType,fun,false)
}else if(ele.attachEvent){
ele.attachEvent('on'+eventType,fun)
}else{
ele['on'+eventType] = fun
}
}
function removeEvent(ele,eventType,fun){
if(ele.removeEventListener){
ele.removeEventListener(eventType,fun,false)
}else if(ele.detachEvent){
ele.detachEvent('on'+eventType,fun)
}else{
ele['on'+eventType] = null
}
}
function getTarget(event){
return event.target || event.srcElement;
}
function getEvent(event){
return event || window.event
}
function stopPropagation(event){
if(event.stopPropagation){
event.stopPropagation()
}else{
event.cancelBubble = true
}
}
function preventDefault(event){
if(event.preventDefault){
event.preventDefault()
}else{
event.returnValue = false
}
}
function getType(o){
return Object.prototype.toString.call(o).slice(8,-1)
}
function jsonp(url, params, callback) {
let querystring = url.indexOf('?') === -1 ? '?' : '&' // 判断是否含有参数
// 添加参数
for (var k in params) {
if (params.hasOwnProperty(k)) {
querystring += k + '=' + params[k] + '&'
}
}
// 处理回调函数名
let random = Math.random().toString().replace('.', ''),
callbackName = "myJsonp" + random;
// 添加回调函数
querystring += 'callback=' + callbackName
// 构建请求
let scriptNode = document.createElement("script")
scriptNode.src = url + querystring
window[callbackName] = function () {
// 调用回调函数
callback(...arguments)
// 删除这个引入的脚本
document.getElementsByTagName('head')[0].removeChild(scriptNode)
}
// 发起请求
document.getElementsByTagName('head')[0].appendChild(scriptNode)
}
var events = (function () {
var topics = {};
return {
// 注册监听函数
subscribe: function (topic, handler) {
if (!topics.hasOwnProperty(topic)) {
topics[topic] = [];
}
topics[topic].push(handler);
},
// 发布事件,触发观察者回调事件
publish: function (topic, info) {
if (topics.hasOwnProperty(topic)) {
topics[topic].forEach(function (handler) {
handler(info);
});
}
},
// 移除主题的一个观察者的回调事件
remove: function (topic, handler) {
if (!topics.hasOwnProperty(topic)) return;
var handlerIndex = -1;
topics[topic].forEach(function (item, index) {
if (item === handler) {
handlerIndex = index;
}
});
if (handlerIndex >= 0) {
topics[topic].splice(handlerIndex, 1);
}
},
// 移除主题的所有观察者的回调事件
removeAll: function (topic) {
if (topics.hasOwnProperty(topic)) {
topics[topic] = [];
}
}
};
})();
//主题监听函数
var handler = function (info) {
console.log(info);
}
//订阅hello主题
events.subscribe('hello', handler);
//发布hello主题
events.publish('hello', 'hello world');
function findMostWord(article) {
if (!article) return false
article = article.trim().toLowerCase() // 清除两端空字符串并转为小写
let wordlist = article.match(/[a-z]+/g), // 将文章中的每个单词转换成数组中的每一项元素
visited = [],
maxNum = 0,
maxWord = '';
article = " " + wordlist.join(" ") + " ";
// 遍历判断单词出现次数
wordlist.forEach(function (item) {
if (visited.indexOf(item) === -1) {
visited.push(item)
let wrod = new RegExp(" " + item + " ", "g"), // 正则 全局匹配 当前单词
num = article.match(wrod).length; // 当前单词出现的个数
if (num > maxNum) {
maxNum = num
maxWord = item
}
}
})
return maxWord + " " + maxNum
}
function getClimbingWays(n){
if(n<1) return 0;
if(n===1) return 1;
if(n===2) return 2;
lat a = 1,
b = 2,
temp = 0;
for(let i = 3;i<=n;i++){
temp = a + b;
a = b;
b = temp;
}
return temp;
}
function bigNumberAdd(str1, str2) {
let result = "", // 保存最后结果
carry = false; // 保留进位结果
// 将字符串转换为数组
str1 = str1.split("");
str2 = str2.split("");
// 当数组的长度都变为 0,并且最终不再进位时,结束循环
while (str1.length || str2.length || carry) {
// 每次将最后的数字进行相加,使用~~的好处是,即使返回值为 undefined 也能转换为 0
carry += ~~str1.pop() + ~~str2.pop();
// 取加法结果的个位加入最终结果
result = carry % 10 + result;
// 判断是否需要进位,true 和 false 的值在加法中会被转换为 1 和 0
carry = carry > 9; }
// 返回最终结果
return result;
}
function flattenArray(array){
if(!Array.isArray(array)) return false;
let result = []
result = array.reduce(function(prev,cur){
return prev.concat(Array.isArray(cur)? flattenArray(cur) : cur)
},[])
return result;
}
function unique(arr){
if (Array.hasOwnProperty('from')) {
return Array.from(new Set(arr));
} else {
var n = {}, r = [];
for (var i = 0; i < arr.length; i++) {
if (!n[arr[i]]) {
n[arr[i]] = true;
r.push(arr[i]);
}
}
return r;
}
}
function arrayMax(arr){
return Math.max.apply(null,arr)
}
function arrayMin(arr){
return Math.min.apply(null,arr)
}
function getMaxCommonDivisor(a, b) {
if (b === 0) return a;
return getMaxCommonDivisor(b, a % b);
}
function getMinCommonMultiple(a, b){
return a * b / getMaxCommonDivisor(a, b);
}
function isPalindrome(str){
let reg = /[\W_]/g, // 匹配所有非单词的字符及下划线
newStr = str.replace(reg,"").toLowerCase() // 替换为空字符并转为小写字母
reverseStr = newStr.split("").reverse().join("") // 将字符串反转
return reverseStr === newStr;
}