1、什么是HTML语义化?
根据内容选择合适的标签,写段落就用p标签,写标题就用h1,让页面具有良好的语义和结构,从而方便人类和机器都能快速理解网页内容
2、meta viewport 是做什么用的,怎么写?
为浏览器提供页面的相关信息,比如针对搜索引擎的关键词
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, minimum-scale=1"><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
viewport 是 meta 标签的 name 属性中可选值中的一个,指 web 页面上用户可见的区域,web页面中的CSS像素的值等于device-width 时,对应到手机上就是占满全屏的宽度,用于移动端页面设计;
initial-scale=1.0 初始化的缩放比例;
maximum-scale=1.0 允许用户最大的缩放比例;
user-scalable=no 为no时不允许用户手动缩放
3、H5是什么?HTML5是什么?XHTML又是什么?
H5是移动网站的一个名称,手机上各种能够被浏览器打开的网页都可以被笼统的称作H5。H5的应用方式主要有:电子邀请函、电子宣传册、企业汇报幻灯片、活动广告、信息收集等。
HTML5 是下一代的 HTML。
XHTML 是以 XML 格式编写的 HTML, 指的是可扩展超文本标记语言,是更严格更纯净的 HTML 版本,XHTML 元素必须合理嵌套,必须有关闭标签,元素必须是小写
https://www.runoob.com/html/html-xhtml.html
4、两种盒模型
W3C的标准盒子模型:content-box
content-box内容盒模型:宽度=内容的宽度,如果后期添加了border或padding就会使盒子向外扩张
IE盒子模型:border-box边框盒模型
border-box边框盒模型:设置的宽度就等于=内容宽度+padding+border;添加的padding和border就在原先设置的width里,border和padding越大就会向内部content扩张,导致content变小
5、flex怎么用,常见的有哪些属性?
在父盒子上写 display:flex
flex-direction:row;//改变子元素流动的方向(主轴)flex-wrap:nowrap; //改变折行justify-content:flex-start;//主轴对齐方式(默认主轴是横轴,除非你改变了flex-direction)align-items:stretch;//次轴第七方式order:1; //按着从小到大排序,-1放在第一位flex-grow:1;//元素的占比大小flex-shrink:5;//当空间不够时,控制谁变瘦,谁值大谁先变瘦的快 ,0时不变瘦,1是默认
6、BFC 是什么?
块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
下列方式会创建块格式化上下文:
- 根元素(`<html>)`- 浮动元素(元素的 [`float`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/float) 不是 `none`)- 绝对定位元素(元素的 [`position`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/position) 为 `absolute` 或 `fixed`)- 行内块元素(元素的 [`display`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/display) 为 `inline-block`)- [`overflow`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/overflow) 值不为 `visible` 的块元素- [`display`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/display) 值为 `[flow-root](https://drafts.csswg.org/css-display/#valdef-display-flow-root)` 的元素- [`contain`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/contain) 值为 `layout`、`content `或 paint 的元素- 弹性元素([`display`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/display) 为 `flex` 或 `inline-flex `元素的直接子元素)- 网格元素([`display`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/display) 为 `grid` 或 `inline-grid` 元素的直接子元素)
块格式化上下文包含创建它的元素内部的所有内容.
7、清除浮动
.clearfix:after{content: '';display: block; /*或者 table*/clear: both;}.clearfix{zoom: 1; /* IE 兼容*/}
ES 6 语法知道哪些,分别怎么用?
块级作用域:使用{}括起来的就是块级作用域
通过var声明的变量没有块级作用域
使用 let和const使用 有块级作用域的。
使用function函数声明,同样被限制在声明他的语句块内;
箭头函数
析构赋值: 又叫 解构赋值 语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。
let a, b, rest;[a, b] = [10, 20];console.log(a);// expected output: 10console.log(b);// expected output: 20[a, b, ...rest] = [10, 20, 30, 40, 50];console.log(rest);// expected output: Array [30,40,50]
https://fangyinghang.com/es-6-tutorials/
同步和异步
同步: 要等任务执行完,得到结果,才执行下一个任务。是所有的操作都做完,才返回给用户结果。即写完数据库之后,再响应用户,用户体验不好。
function A = function(){return '同步任务的返回值'}var result = A() // 那么 result 就是同步任务的结果B() // 然后执行下一个任务
异步:不等任务执行完,就直接执行下一个任务;书写顺序和执行顺序不一样。不用等所有操作都做完,就响应用户请求。即先响应用户请求,然后慢慢去写数据库,用户体验较好。
下面这个代码的书写顺序是 1 -> 2 -> 3;但是执行顺序是 1 -> 3 -> 2。这就是异步
console.log(1)setTimeout(function(){console.log(2)},0)console.log(3)
如何判断同步异步?
如果一个函数的返回值处于 setTimeout, AJAX,addEventListener这三个东西内部,那么这个函数就是异步函数
Promise、Promise.all、Promise.race 分别怎么用?
Promise 是异步编程的一种解决方案:表示一个异步操作的最终状态以及返回的值;
从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
promise的用法:
一个Promise必须提供一个 then 方法以访问其当前值、终值和据因。promise.then(onFulfilled, onRejected)回调函数只能执行一次,且返回 promise 对象Promise的每个操作返回的都是Promise对象,可支持链式调用。
通过 then 方法执行回调函数,Promise的回调函数是放在事件循环中的微队列。
function fn(){return new Promise((resolve, reject)=>{成功时调用 resolve(数据)失败时调用 reject(错误)})}fn().then(success, fail).then(success2, fail2)
Promise.all 用法Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。promise1和promise2都成功才会调用success1
Promise.all([promise1, promise2]).then(success1, fail1)
Promise.race 用法Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。promise1和promise2只要有一个成功就会调用succ ess1promise1和promise2只要有一个失败就会调用fail1;
总之,谁第一个成功或失败,就认为是race的成功或失败。
Promise.race([promise1, promise2]).then(success1, fail1)
函数节流和函数防抖
函数节流:任务在指定的间隔时间内只执行一次。
// 节流(一段时间执行一次之后,就不执行第二次)function throttle(fn, delay){let canUse = truereturn function(){if(canUse){fn.apply(this, arguments)canUse = falsesetTimeout(()=>canUse = true, delay)}}}const throttled = throttle(()=>console.log('hi'))throttled()throttled()
函数防抖:只有在任务触发的间隔大于等于指定的间隔时间,任务才会被执行。(点击了之后先不做,等了一定的时间之后再做)
// 防抖(一段时间会等,然后带着一起做了)function debounce(fn, delay){let timerId = nullreturn function(){const context = thisif(timerId){window.clearTimeout(timerId)}timerId = setTimeout(()=>{fn.apply(context, arguments)timerId = null},delay)}}const debounced = debounce(()=>console.log('hi'))debounced()debounced()
AJAX
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
var request = new XMLHttpRequest()request.open('GET', '/a/b/c?name=ff', true);request.onreadystatechange = function() {if(request.readyState === 4 && request.status === 200) {console.log(request.responseText);}};request.send();
简化版代码
var request = new XMLHttpRequest()request.open('GET', '/a/b/c?name=ff', true)request.onload = ()=> console.log(request.responseText)request.send()
this
this是JavaScript关键字,在非严格模式下,它总是指向一个对象,而具体指向哪个对象是根据函数运行时所在的执行环境动态绑定的。
为什么需要 this
因为函数可以在不同的运行环境中执行,自身调用或作为方法调用,为了得到当前函数真正运行时的所在执行环境,即函数执行时真正的调用对象,this机制就此诞生了。
fn()this => window/globalobj.fn()this => objfn.call(xx)this => xxfn.apply(xx)this => xxfn.bind(xx)this => xxnew Fn()this => 新的对象fn = ()=> {}this => 外面的 this
闭包和立即执行函数
闭包:如果一个函数用到了外部的变量,那么这个函数加这个变量,就叫做闭包
1和22
闭包的作用:闭包常常用来‘间接访问一个变量’。换句话说,隐藏一个变量。
内存泄露是指你用不到(访问不到)的变量,依然占居着内存空间,不能被再次利用起来。
立即执行函数是什么
立即执行函数:1.声明一个匿名函数
2.马上调用这个匿名函数

匿名函数后面接一对括号 (),调用这个匿名函数。
那么为什么还要用另一对括号把匿名函数包起来呢?
如果不加另一对括号,直接写成
function(){alert('我是匿名函数')}()
立即执行函数的作用
只有一个作用:创建一个独立的作用域。
这个作用域里面的变量,外面访问不到(即避免「变量污染」)。
面试题
let i;for(i=0; i<6; i++){setTimeout(fn()=>{console.log(i);},1000);// 为什么 打印 出来的总是 6,而不是 0、1、2、3、4、5}
为什么 打印的总是 6 呢,因为 i 是贯穿整个作用域的,setTimeout函数是当1000毫秒执行完后就执行,但此时i已经等于6了
那么怎么解决这个问题呢?
解法1:把let i=0写道for循环里,这样会对每一次循环创建一个新的作用域,i会保留此时的值
解法2:用立即执行函数给每个i创造一个独立作用域即可
//解法1for(let i=0; i<6; i++){setTimeout(fn()=>{console.log(i);},1000);}//解法2for(let i=0; i<6; i++){!function(){setTimeout(()=> console.log(i),1000);}(i)}
什么是跨域,什么是 JSONP,什么是 CORS
跨域
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议有一个不同,都是跨域;
即指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制
同源策略
同源定义: 如果两个url的协议,域名,端口号完全一致,那么这两个url就是同源的
源: 在任意一个浏览器打印 window.origin 或location.origin可以得到当前源
源=协议+域名+端口号
同源策略定义: 浏览器规定,如果JS运行在源A里,那么就只能获取源A的数据不能获取源B的数据,即不允许跨域。目的就是为了保护用户隐私
CORS
CORS: 跨源资源共享
就是解决不同源之间数据的访问
在被访问源的响应头里提前声明,指明此数据谁可以访问: [http://dong.com:9990](http://dong.com:9990)可以访问了
response.setHeader("Access-Control-Allow-Origin", "http://dong.com:9990");

但是IE 6,7,8,9 不支持CORS,可以使用JSONP
JSONP
JSONP:在跨域的时候浏览器不支持cors,必须使用另外一种方式跨域,于是我们就请求一个js文件,这个js文件会执行一个回调,回调里面就有我们的数据,回调函数名字可以是一个随机数,把这个名字以callback参数传给后台,后台会把这个参数返回过来并执行;
优点: 兼容ie,可以跨域
缺点: 由于是script标签,它拿不到状态码和响应头,只知道成功和失败,只能发get请求,不支持post
1.jsonp跨域方法是新建一个js文件里面写上一个占位符{{data}}2.在后端路由里将json数据文件转化成字符串3.再将js文件转化成字符串4.然后用json字符串 替换掉{{data}}

这样就可以跨域访问了,但是还是有一个问题,这个js所有人都可以访问,不安全
解决方法:是由referer检验,在路由哪判断一下是否允许访问
如何实现深拷贝?
- 浅拷贝:是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
- 深拷贝:是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
使用递归实现深拷贝
function deepClone1(obj) {//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝var objClone = Array.isArray(obj) ? [] : {};//进行深拷贝的不能为空,并且是对象或者是if (obj && typeof obj === "object") {for (key in obj) {console.log(key,'key')if (obj.hasOwnProperty(key)) {if (obj[key] && typeof obj[key] === "object") {objClone[key] = deepClone1(obj[key]);} else {objClone[key] = obj[key];}}}}else{console.log(key,'ke11y')}return objClone;}var ma={ma1:2}// var ma=[2,3,3]deepClone1(ma)
async/await 怎么用,如何捕获异常?
https://es6.ruanyifeng.com/?search=async&x=0&y=0#docs/async
不用 class 如何实现继承?用class 又如何实现?
不用class
function Animal(color){this.color = color}Animal.prototype.move = function(){} // 动物可以动function Dog(color, name){Animal.call(this, color) // 或者 Animal.apply(this, arguments)this.name = name}// 下面三行实现 Dog.prototype.__proto__ = Animal.prototypefunction temp(){}temp.prototype = Animal.prototypeDog.prototype = new temp()Dog.prototype.constuctor = Dog // 这行看不懂就算了,面试官也不问Dog.prototype.say = function(){ console.log('汪')}var dog = new Dog('黄色','阿黄')
用 class 就简单了
class Animal{constructor(color){this.color = color}move(){}}class Dog extends Animal{constructor(color, name){super(color)this.name = name}say(){}}
如何用正则实现 trim()?
String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, '')}//或者function trim(string){return string.replace(/^\s+|\s+$/g, '')}
