共计 7330 个字符,预计需要花费 19 分钟才能阅读完成。
为什么 0.1 + 0.2 != 0.3,请详述理由
因为 JS 采纳 IEEE 754 双精度版本(64 位),并且只有采纳 IEEE 754 的语言都有该问题。
咱们都晓得计算机示意十进制是采纳二进制示意的,所以 0.1
在二进制示意为
// (0011) 示意循环
0.1 = 2^-4 * 1.10011(0011)
那么如何失去这个二进制的呢,咱们能够来演算下
小数算二进制和整数不同。乘法计算时,只计算小数位,整数位用作每一位的二进制,并且失去的第一位为最高位。所以咱们得出 0.1 = 2^-4 * 1.10011(0011)
,那么 0.2
的演算也根本如上所示,只须要去掉第一步乘法,所以得出 0.2 = 2^-3 * 1.10011(0011)
。
回来持续说 IEEE 754 双精度。六十四位中符号位占一位,整数位占十一位,其余五十二位都为小数位。因为 0.1
和 0.2
都是有限循环的二进制了,所以在小数位开端处须要判断是否进位(就和十进制的四舍五入一样)。
所以 2^-4 * 1.10011...001
进位后就变成了 2^-4 * 1.10011(0011 * 12 次)010
。那么把这两个二进制加起来会得出 2^-2 * 1.0011(0011 * 11 次)0100
, 这个值算成十进制就是 0.30000000000000004
上面说一下原生解决办法,如下代码所示
parseFloat((0.1 + 0.2).toFixed(10))
常⽤的 meta 标签有哪些
meta
标签由 name
和 content
属性定义,用来形容网页文档的属性 ,比方网页的作者,网页形容,关键词等,除了 HTTP 规范固定了一些name
作为大家应用的共识,开发者还能够自定义 name。
罕用的 meta 标签:
(1)charset
,用来形容 HTML 文档的编码类型:
<meta charset="UTF-8" >
(2)keywords
,页面关键词:
<meta name="keywords" content="关键词" />
(3)description
,页面形容:
<meta name="description" content="页面形容内容" />
(4)refresh
,页面重定向和刷新:
<meta http-equiv="refresh" content="0;url=" />
(5)viewport
,适配挪动端,能够管制视口的大小和比例:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
其中,content
参数有以下几种:
width viewport
:宽度(数值 /device-width)height viewport
:高度(数值 /device-height)initial-scale
:初始缩放比例maximum-scale
:最大缩放比例minimum-scale
:最小缩放比例user-scalable
:是否容许用户缩放(yes/no)
(6)搜索引擎索引形式:
<meta name="robots" content="index,follow" />
其中,content
参数有以下几种:
all
:文件将被检索,且页面上的链接能够被查问;none
:文件将不被检索,且页面上的链接不能够被查问;index
:文件将被检索;follow
:页面上的链接能够被查问;noindex
:文件将不被检索;nofollow
:页面上的链接不能够被查问。
说一下 SPA 单页面有什么优缺点?
长处:1. 体验好,不刷新,缩小 申请 数据 ajax 异步获取 页面流程;2. 前后端拆散
3. 加重服务端压力
4. 共用一套后端程序代码,适配多端
毛病:1. 首屏加载过慢;2.SEO 不利于搜索引擎抓取
const 对象的属性能够批改吗
const 保障的并不是变量的值不能改变,而是变量指向的那个内存地址不能改变。对于根本类型的数据(数值、字符串、布尔值),其值就保留在变量指向的那个内存地址,因而等同于常量。
但对于援用类型的数据(次要是对象和数组)来说,变量指向数据的内存地址,保留的只是一个指针,const 只能保障这个指针是固定不变的,至于它指向的数据结构是不是可变的,就齐全不能管制了。
JS 隐式转换,显示转换
个别非根底类型进行转换时会先调用 valueOf,如果 valueOf 无奈返回根本类型值,就会调用 toString
字符串和数字
- “+” 操作符,如果有一个为字符串,那么都转化到字符串而后执行字符串拼接
- “-” 操作符,转换为数字,相减 (-a, a * 1 a/1) 都能进行隐式强制类型转换
[] + {} 和 {} + []
布尔值到数字
- 1 + true = 2
- 1 + false = 1
转换为布尔值
- for 中第二个
- while
- if
- 三元表达式
- ||(逻辑或)&&(逻辑与)右边的操作数
符号
- 不能被转换为数字
- 能被转换为布尔值(都是 true)
- 能够被转换成字符串 “Symbol(cool)”
宽松相等和严格相等
宽松相等容许进行强制类型转换,而严格相等不容许
字符串与数字
转换为数字而后比拟
其余类型与布尔类型
- 先把布尔类型转换为数字,而后持续进行比拟
对象与非对象
- 执行对象的 ToPrimitive(对象)而后持续进行比拟
假值列表
- undefined
- null
- false
- +0, -0, NaN
- “”
对盒模型的了解
CSS3 中的盒模型有以下两种:规范盒子模型、IE 盒子模型 盒模型都是由四个局部组成的,别离是 margin、border、padding 和 content。
规范盒模型和 IE 盒模型的区别在于设置 width 和 height 时,所对应的范畴不同:
- 规范盒模型的 width 和 height 属性的范畴只蕴含了 content,
- IE 盒模型的 width 和 height 属性的范畴蕴含了 border、padding 和 content。
能够通过批改元素的 box-sizing 属性来扭转元素的盒模型:
box-sizeing: content-box
示意规范盒模型(默认值)box-sizeing: border-box
示意 IE 盒模型(怪异盒模型)
如何阻止事件冒泡
- 一般浏览器应用:event.stopPropagation()
- IE 浏览器应用:event.cancelBubble = true;
懒加载的概念
懒加载也叫做提早加载、按需加载,指的是在长网页中提早加载图片数据,是一种较好的网页性能优化的形式。在比拟长的网页或利用中,如果图片很多,所有的图片都被加载进去,而用户只能看到可视窗口的那一部分图片数据,这样就节约了性能。
如果应用图片的懒加载就能够解决以上问题。在滚动屏幕之前,可视化区域之外的图片不会进行加载,在滚动屏幕时才加载。这样使得网页的加载速度更快,缩小了服务器的负载。懒加载实用于图片较多,页面列表较长(长列表)的场景中。
常见的 HTTP 申请办法
- GET: 向服务器获取数据;
- POST:将实体提交到指定的资源,通常会造成服务器资源的批改;
- PUT:上传文件,更新数据;
- DELETE:删除服务器上的对象;
- HEAD:获取报文首部,与 GET 相比,不返回报文主体局部;
- OPTIONS:询问反对的申请办法,用来跨域申请;
- CONNECT:要求在与代理服务器通信时建设隧道,应用隧道进行 TCP 通信;
- TRACE: 回显服务器收到的申请,次要⽤于测试或诊断。
代码输入后果
Promise.reject('err!!!')
.then((res) => {console.log('success', res)
}, (err) => {console.log('error', err)
}).catch(err => {console.log('catch', err)
})
输入后果如下:
error err!!!
咱们晓得,.then
函数中的两个参数:
- 第一个参数是用来解决 Promise 胜利的函数
- 第二个则是解决失败的函数
也就是说 Promise.resolve('1')
的值会进入胜利的函数,Promise.reject('2')
的值会进入失败的函数。
在这道题中,谬误间接被 then
的第二个参数捕捉了,所以就不会被 catch
捕捉了,输入后果为:error err!!!'
然而,如果是像上面这样:
Promise.resolve()
.then(function success (res) {throw new Error('error!!!')
}, function fail1 (err) {console.log('fail1', err)
}).catch(function fail2 (err) {console.log('fail2', err)
})
在 then
的第一参数中抛出了谬误,那么他就不会被第二个参数不活了,而是被前面的 catch
捕捉到。
行内元素有哪些?块级元素有哪些?空 (void) 元素有那些?
- 行内元素有:
a b span img input select strong
; - 块级元素有:
div ul ol li dl dt dd h1 h2 h3 h4 h5 h6 p
;
空元素,即没有内容的 HTML 元素。空元素是在开始标签中敞开的,也就是空元素没有闭合标签:
- 常见的有:
<br>
、<hr>
、<img>
、<input>
、<link>
、<meta>
; - 鲜见的有:
<area>
、<base>
、<col>
、<colgroup>
、<command>
、<embed>
、<keygen>
、<param>
、<source>
、<track>
、<wbr>
。
代码输入后果
console.log(1)
setTimeout(() => {console.log(2)
})
new Promise(resolve => {console.log(3)
resolve(4)
}).then(d => console.log(d))
setTimeout(() => {console.log(5)
new Promise(resolve => {resolve(6)
}).then(d => console.log(d))
})
setTimeout(() => {console.log(7)
})
console.log(8)
输入后果如下:
1
3
8
4
2
5
6
7
代码执行过程如下:
- 首先执行 script 代码,打印出 1;
- 遇到第一个定时器,退出到宏工作队列;
- 遇到 Promise,执行代码,打印出 3,遇到 resolve,将其退出到微工作队列;
- 遇到第二个定时器,退出到宏工作队列;
- 遇到第三个定时器,退出到宏工作队列;
- 继续执行 script 代码,打印出 8,第一轮执行完结;
- 执行微工作队列,打印出第一个 Promise 的 resolve 后果:4;
- 开始执行宏工作队列,执行第一个定时器,打印出 2;
- 此时没有微工作,继续执行宏工作中的第二个定时器,首先打印出 5,遇到 Promise,首选打印出 6,遇到 resolve,将其退出到微工作队列;
- 执行微工作队列,打印出 6;
- 执行宏工作队列中的最初一个定时器,打印出 7。
对 this 对象的了解
this 是执行上下文中的一个属性,它指向最初一次调用这个办法的对象。在理论开发中,this 的指向能够通过四种调用模式来判断。
- 第一种是 函数调用模式,当一个函数不是一个对象的属性时,间接作为函数来调用时,this 指向全局对象。
- 第二种是 办法调用模式,如果一个函数作为一个对象的办法来调用时,this 指向这个对象。
- 第三种是 结构器调用模式,如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象。
- 第四种是 apply、call 和 bind 调用模式,这三个办法都能够显示的指定调用函数的 this 指向。其中 apply 办法接管两个参数:一个是 this 绑定的对象,一个是参数数组。call 办法接管的参数,第一个是 this 绑定的对象,前面的其余参数是传入函数执行的参数。也就是说,在应用 call() 办法时,传递给函数的参数必须一一列举进去。bind 办法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了应用 new 时会被扭转,其余状况下都不会扭转。
这四种形式,应用结构器调用模式的优先级最高,而后是 apply、call 和 bind 调用模式,而后是办法调用模式,而后是函数调用模式。
什么是 DOM 和 BOM?
- DOM 指的是文档对象模型,它指的是把文档当做一个对象,这个对象次要定义了解决网页内容的办法和接口。
- BOM 指的是浏览器对象模型,它指的是把浏览器当做一个对象来看待,这个对象次要定义了与浏览器进行交互的法和接口。BOM 的外围是 window,而 window 对象具备双重角色,它既是通过 js 拜访浏览器窗口的一个接口,又是一个 Global(全局)对象。这意味着在网页中定义的任何对象,变量和函数,都作为全局对象的一个属性或者办法存在。window 对象含有 location 对象、navigator 对象、screen 对象等子对象,并且 DOM 的最基本的对象 document 对象也是 BOM 的 window 对象的子对象。
写代码:实现函数可能深度克隆根本类型
浅克隆:
function shallowClone(obj) {let cloneObj = {};
for (let i in obj) {cloneObj[i] = obj[i];
}
return cloneObj;
}
深克隆:
- 思考根底类型
-
援用类型
- RegExp、Date、函数 不是 JSON 平安的
- 会失落 constructor,所有的构造函数都指向 Object
- 破解循环援用
function deepCopy(obj) {if (typeof obj === 'object') {var result = obj.constructor === Array ? [] : {};
for (var i in obj) {result[i] = typeof obj[i] === 'object' ? deepCopy(obj[i]) : obj[i];
}
} else {var result = obj;}
return result;
}
Promise.any
形容 :只有 promises
中有一个fulfilled
,就返回第一个fulfilled
的Promise
实例的返回值。
实现
Promise.any = function(promises) {return new Promise((resolve, reject) => {if(Array.isArray(promises)) {if(promises.length === 0) return reject(new AggregateError("All promises were rejected"));
let count = 0;
promises.forEach((item, index) => {Promise.resolve(item).then(value => resolve(value),
reason => {
count++;
if(count === promises.length) {reject(new AggregateError("All promises were rejected"));
};
}
);
})
}
else return reject(new TypeError("Argument is not iterable"));
});
}
为什么 udp 不会粘包?
- TCP 协定是⾯向流的协定,UDP 是⾯向音讯的协定。UDP 段都是⼀条音讯,应⽤程序必须以音讯为单位提取数据,不能⼀次提取任意字节的数据
- UDP 具备爱护音讯边界,在每个 UDP 包中就有了音讯头(消息来源地址,端⼝等信息),这样对于接收端来说就容易进⾏辨别解决了。传输协定把数据当作⼀条独⽴的音讯在⽹上传输,接收端只能接管独⽴的音讯。接收端⼀次只能接管发送端收回的⼀个数据包, 如果⼀次承受数据的⼤⼩⼩于发送端⼀次发送的数据⼤⼩,就会失落⼀局部数据,即便失落,承受端也不会分两次去接管。
== 操作符的强制类型转换规定?
对于 ==
来说,如果比照单方的类型 不一样 ,就会进行 类型转换。如果比照 x
和 y
是否雷同,就会进行如下判断流程:
- 首先会判断两者类型是否 雷同,雷同的话就比拟两者的大小;
- 类型不雷同的话,就会进行类型转换;
- 会先判断是否在比照
null
和undefined
,是的话就会返回true
- 判断两者类型是否为
string
和number
,是的话就会将字符串转换为number
1 == '1'
↓
1 == 1
- 判断其中一方是否为
boolean
,是的话就会把boolean
转为number
再进行判断
'1' == true
↓
'1' == 1
↓
1 == 1
- 判断其中一方是否为
object
且另一方为string
、number
或者symbol
,是的话就会把object
转为原始类型再进行判断
'1' == {name: 'js'} ↓'1' == '[object Object]'
应用 clear 属性革除浮动的原理?
应用 clear 属性革除浮动,其语法如下:
clear:none|left|right|both
如果单看字面意思,clear:left 是“革除左浮动”,clear:right 是“革除右浮动”,实际上,这种解释是有问题的,因为浮动始终还在,并没有革除。
官网对 clear 属性解释:“元素盒子的边不能和后面的浮动元素相邻”,对元素设置 clear 属性是为了防止浮动元素对该元素的影响,而不是革除掉浮动。
还须要留神 clear 属性指的是元素盒子的边不能和后面的浮动元素相邻,留神这里“后面的”3 个字,也就是 clear 属性对“前面的”浮动元素是充耳不闻的。思考到 float 属性要么是 left,要么是 right,不可能同时存在,同时因为 clear 属性对“前面的”浮动元素充耳不闻,因而,当 clear:left 无效的时候,clear:right 必然有效,也就是此时 clear:left 等同于设置 clear:both;同样地,clear:right 如果无效也是等同于设置 clear:both。由此可见,clear:left 和 clear:right 这两个申明就没有任何应用的价值,至多在 CSS 世界中是如此,间接应用 clear:both 吧。
个别应用伪元素的形式革除浮动:
.clear::after{content:''; display: block; clear:both;}
clear 属性只有块级元素才无效的,而::after 等伪元素默认都是内联程度,这就是借助伪元素革除浮动影响时须要设置 display 属性值的起因。