1.对象如何判断属性是否存在
定义如下obj对象
// 自有属性
const obj = {
a: undefined
}
//原型上的属性
obj.__proto__.b = undefined
// 定义不可枚举的属性
Object.defineProperties(obj,{'c':{
value:1 ,
enumerable:false,
}
})
//获取属性描述
Object.getOwnPropertyDescriptors(obj,"a")
if ("a" in obj) {
console.log("a 存在")
}
if ("b" in obj) {
console.log("b 存在")
}
if ("c" in obj) {
console.log("c 存在")
}
- 通过
Object.keys(obj).includes("c")
判断,只能判断自有属性
,无法判断原型上的属性
和不可枚举的属性
- 通过
obj.hasOwnProperty("c")
,可以判断自有属性
和不可枚举的属性
,不能判断原型上的属性
- 通过
if ("a" in obj)
,是es6语法,三种都可以判断
2.数据类型和typeOf
js中是否存在精确的计时?
不存在,从以下4个方面
- 硬件: 没有绝对的精确,只有相对精确(计算机使用cpu寄存器计时)
- 系统: 浏览器调用操作系统计时间
- 标准: w3c,如果settimeout 嵌套层级>=5 ,最小耗时4ms时间
- 事件循环: 回调函数必须等待执行栈清空
判断是否是数组
有3种方式如下
// 方式1
function isArrayOne(list){
const data = Object.prototype.toString.call(list)
console.log("data",data);
if(data === '[object Array]'){
return true;
}
return false;
}
const arr = [1,2,3,4]
//缺点,可以通过Symbol修改字符串
const obj = {
[Symbol.toStringTag] : 'Array'
}
console.log("obj",isArrayOne(obj))
//方式2
function isArrayTwo(list){
if(arr instanceof Array){
return true
}
return false
}
// 当前window Array
const Array1 = window.Array;
const iframe = document.querySelector('iframe');
const Array2 = iframe.contentWindow.Array;
// 方式2的缺点
// 如果是iframe下面的Array ,方式2的判断会有问题
console.log("方式2:",Array1 === Array2);
//最佳方式3
// 方式3 精确的判断
function isArrayThree(list){
if(Array.isArray(arr)){
return true;
}
return false
}
如何打破谷歌浏览器最小字体限制
谷歌浏览器默认的最小字体大小为12,即使我们把字体变为<12,也无法改变,这给时候我们可以使用缩放
.font-scale{
font-size: 20px;
transform: scale(0.5);
display: inline-block;
transform-origin: left center;
}
判断一个指是否是Promise Like
// 根据promise A+ 规范
function isPromiseLike(value){
// 1.是对象或者函数
// 2.并且 then 方法是函数
return (value !== null &&
(typeof value === 'object' || typeof value === 'function') &&
(typeof value.then === 'function'))
}
Proxy 和defineProperty到底哪个好
- defineProperty 需要深度遍历每一个对象, 通过在get 和set方法做一些处理
如果后续需要增加和删除属性则无法接听
- proxy直接监听整个对象
前端实现滚动元素到可视区域
常用的有2种方式如下
使用浏览器的锚点来实现
<!-- 给目标元素设置一个唯一的id -->
<div class="targetIdName">
</div>
<!-- 通过a元素创建一个带有锚点的链接 -->
<a href="#targetIdName"></a>
-
优点:使用方便,可以分享后带链接跳转
-
缺点:1. 无法滚动到精确位置
-
缺点: 使用vue和react框架开发使用hash路由的时候会造成冲突
使用Js实现
通过scrollIntoView({behavior:'smooth',block:'start'}) 来实现
el:当前元素 behavior: 滑动行为 block:垂直方向的对齐 (start、center、end)
实现并发请求
需求如下:
- 封装一个函数,传入参数1:需要并非的请求地址,参数2:同时并发的最大数量
- 所有数据请求完成后,有序的返回各个借口的数据
直接上代码
function concurReq(urlList,maxNum){
// 如果数组为空,直接返回空数组
if(urlList.length == 0) return Promise.resolve([]);
//指向下一次请求url的下表
let index = 0;
let count = 0; //当前完成的请求数量
// 保存请求的结果
const result = [];
return new Promise((resolve)=>{
// 单个接口请求
async function _request(){
const i = index;
const url = urlList[index];
index++;
try {
const resp = await fetch(url);
result[i] = resp
} catch (error) {
result[i] = error
}
finally{
count++;
if(count === urlList.length){
resolve(result)
}
if(index < urlList.length){
_request();
}
}
}
// 并发请求的最大数量
for(let i = 0;i<Math.min(maxNum,urlList.length);i++){
_request();
}
})
}