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: 10
console.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 ess1
promise1
和promise2
只要有一个失败就会调用fail1
;
总之,谁第一个成功或失败,就认为是race的成功或失败。
Promise.race([promise1, promise2]).then(success1, fail1)
函数节流和函数防抖
函数节流:任务在指定的间隔时间内只执行一次。
// 节流(一段时间执行一次之后,就不执行第二次)
function throttle(fn, delay){
let canUse = true
return function(){
if(canUse){
fn.apply(this, arguments)
canUse = false
setTimeout(()=>canUse = true, delay)
}
}
}
const throttled = throttle(()=>console.log('hi'))
throttled()
throttled()
函数防抖:只有在任务触发的间隔大于等于指定的间隔时间,任务才会被执行。(点击了之后先不做,等了一定的时间之后再做)
// 防抖(一段时间会等,然后带着一起做了)
function debounce(fn, delay){
let timerId = null
return function(){
const context = this
if(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/global
obj.fn()
this => obj
fn.call(xx)
this => xx
fn.apply(xx)
this => xx
fn.bind(xx)
this => xx
new 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创造一个独立作用域即可
//解法1
for(let i=0; i<6; i++){
setTimeout(fn()=>{
console.log(i);
},1000);
}
//解法2
for(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.prototype
function temp(){}
temp.prototype = Animal.prototype
Dog.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, '')
}