前端javascript常见问题总结
一、javscript部分
1、如何判断一个对象是否为空对象?
- 方法1:
let obj1 = {}
let obj2 = {a:1}
function empty(obj){for (let key in obj){return false; //非空
}return true; //为空
}
console.log(empty(obj1)) //true为空
console.log(empty(obj2)) //false非空
- 方法2
let obj1 = {}
let obj2 = {a:1}
function empty(obj){for (let key in obj){return false; //非空
}return true; //为空
}
console.log(empty(obj1)) //true为空
console.log(empty(obj2)) //false非空
- 方法3
let obj1 = {}
let obj2 = {a:1}
function empty(obj){for (let key in obj){return false; //非空
}return true; //为空
}
console.log(empty(obj1)) //true为空
console.log(empty(obj2)) //false非空
- 方法4
Object.keys(obj).length == 0
- 方法5
通过将对象转换吃哼json字符串,进而判断是否为空对象。
function ObjectIsNullOrNot02(param){return JSON.stringify(param)==="{}"?true:false;
}
2、如何判断一个对象是否有某一属性?
- 方法1:
. 或 [ ] 当此属性的值为false、undefined、NaN、null、0、"" 时,此方法不适用。
if (obj2.a){console.log("对象有此属性")
}else {console.log("对象无此属性")
}
- 方法2
in运算符 如果某属性在指定对象或其原型链上则返回true,只需判断自身属性时,此方法不适用。
if (obj2.a){console.log("对象有此属性")
}else {console.log("对象无此属性")
}
- 方法3:
obj.hasOwnProperty() 对象自身属性中含有某属性,返回true。
let obj2 = {a:1}if (obj2.hasOwnProperty("a")){console.log("对象上有此属性")
}else {console.log("对象上无此属性")
}
3、关于数组一些常用方法总结
- map方法
map()方法根据回调函数映射一个新数组
Array.prototype.map=function(fn){const result=[];for(let i=0;i<this.length;i++){if(!this.hasOwnProperty(i)) continue; //处理是稀疏数组的情况result.push(fn(this[i],i,this));}return result;}
// 使用// const arr_m=[1,2,3,,5];// const mapArr=arr_m.map(item=>item * 2);// console.log(mapArr);
- filter方法
filter()方法返回一个数组,返回的每一项是在回调函数中执行结果true。
Array.prototype.filter=function(fn){const result=[];for(let i=0;i<this.length;i++){if(!this.hasOwnProperty(i)) continue;fn(this[i],i,this) && result.push(this[i]);}return result;}// 使用// const arr_f=[1,2,3,,5];// const fliterArr=arr_f.filter(item=>item > 2);// console.log(fliterArr);
- every方法
every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值
Array.prototype.every=function(fn){let bool=true;for(let i=0;i<this.length;i++){if(!this.hasOwnProperty(i)) continue;if(!fn(this[i],i,this)){bool=false;break;}}return bool;}// 使用// const arr_e=[1,2,3,5];// const everyArr=arr_e.every(item=>item>3);// console.log(everyArr);
- some方法
some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。
Array.prototype.some=function(fn){let bool=false;for(let i=0;i<this.length;i++){if(!this.hasOwnProperty(i)) continue;if(fn(this[i],i,this)){bool=true;break;}}return bool;}// const arr_s=[1,2,3,5];// const someArr=arr_s.some(item=>item>3);// console.log(someArr);
- find方法
find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
Array.prototype.find=function(fn){let result;for(let i=0;i<this.length;i++){if(!this.hasOwnProperty(i)) continue;if(fn(this[i],i,this)){result=this[i];break;}}return result;}// const arr_f=[1,2,3,5];// const findArr=arr_f.find(item=>item>6);// console.log(findArr);
- reduce方法
Array.prototype.reduce=function(fn,initValue){let result=initValue?initValue:this[0];for(let i=initValue ? 1:0;i<this.length;i++){if(!this.hasOwnProperty(i)) continue;result=fn(result,this[i],i,this);}return result;}// 使用// const arr_r=[1,2,3,,5];// const reduceArr=arr_r.reduce((a,b)=>a*b,2);// console.log(reduceArr);
- 拉平数组
将嵌套的数组扁平化,在处理业务数据场景中是频率出现比较高的。那如何实现呢?
方法1:利用ES6语法flat(num)方法将数组拉平
该方法不传参数默认只会拉平一层,如果想拉平多层嵌套的数组,需要传入一个整数,表示要拉平的层级。该返回返回一个新的数组,对原数组没有影响。
// 利用flat方法封装function flattening(arr,num=1){if(!Array.isArray(arr)) return;return arr.flat(num);}
方法2:利用reduce()方法将数组拉平。
利用reduce进行迭代,核心的思想是递归实现。
// 利用reduce实现function flattening(arr){if(!Array.isArray(arr)) return;return arr.reduce((a,b)=>a.concat(Array.isArray(b)?flattening(b):a),[]);}
方法3:模拟栈实现数组拉平
该方法是模拟栈,在性能上相对最优解
// 栈实现拉平function flattening(arr){if(!Array.isArray(arr)) return;const stack=[...arr];const res=[];while(stack.length){let value=stack.shift();Array.isArray(value)?stack.push(...value): res.push(value)}return res;}
4、8个常用的Javascript对象方法
- object.is
Object.is() 是一种判断两个值是否相同的方法。
语法:Object.is(value1, value2);
参数:
value1:要比较的第一个值。
value2:要比较的第二个值。
返回值:一个布尔表达式,指示两个参数是否具有相同的值。
// Case 1: Evaluation result is the same as using '==='
Object.is(25, 25); // true
Object.is('foo', 'bar'); // false
Object.is(foo, foo); // true
// Case 2: Signed zero
Object.is(0, -0); // false
Object.is(0n, -0n); // true
// Case 3: NaN
Object.is(NaN, 0/0); // true
Object.is(NaN, Number.NaN) // true
- Object.assign()
Object.assign() 方法用于将所有可枚举的自身属性从一个或多个源对象复制到目标对象。
语法:Object.assign(target, …sources)
参数:
target:目标对象——应用源属性的对象,修改后返回。
sources:源对象——包含你要应用的属性的对象。
返回值:修改后的目标对象
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
注意:如果源对象中的属性具有相同的键,则目标对象中的属性会被源中的属性覆盖。较晚来源的属性会覆盖较早来源的属性。
- Object.entries()
Object.entries() 方法返回给定对象自己的可枚举字符串键属性 [key, value] 对的数组。
它类似于使用 for…in 循环进行迭代,除了 for…in 循环还会枚举原型链中的属性。属性的顺序与通过手动循环对象的属性值给出的顺序相同
参数:
obj:要返回其自己的可枚举字符串键属性 [key, value] 对的对象。
返回值:给定对象自己的可枚举字符串键属性 [key, value] 对的数组。
const object1 = {name: "David", age: 23};
for (const [key, value] of Object.entries(object1)) {console.log(`${key}: ${value}`);
}
// "name: David"
// "age: 23"
- Object.keys()
Object.keys() 方法用于返回给定对象自己的可枚举属性名称的数组,以与普通循环相同的顺序迭代。
const object1 = {a: 'somestring',b: 42,c: false
};
console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]
- Object.prototype.hasOwnProperty()
hasOwnProperty() 方法返回一个布尔值,指示对象是否具有指定的属性作为它自己的属性。
如果指定的属性是对象的直接属性,则该方法返回 true — 即使值为 null 或未定义。如果该属性是继承的或根本没有声明,则返回 false。
const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// expected output: true
console.log(object1.hasOwnProperty('toString'));
// expected output: false
console.log(object1.hasOwnProperty('hasOwnProperty'));
// expected output: false
- Object.prototype.toString()
toString() 方法返回一个表示对象的字符串。当对象将被表示为文本值或以期望字符串的方式引用对象时,将自动调用此方法 id。默认情况下,toString() 方法由从 Object 继承的每个对象继承。
function Dog(name) {this.name = name;
}
const dog1 = new Dog('Gabby');
Dog.prototype.toString = function dogToString() {return `${this.name}`;
};
console.log(dog1.toString());
// expected output: "Gabby"
- Object.values()
Object.values() 方法返回给定对象自己的可枚举属性值的数组,其顺序与 for…in 循环提供的顺序相同。
const object1 = {a: 'somestring',b: 42,c: false
};
console.log(Object.values(object1));
// expected output: Array ["somestring", 42, false]
5、图片懒加载 & 惰性函数
实现图片懒加载其核心的思想就是将img的src属性先使用一张本地占位符,或者为空。然后真实的图片路径再定义一个data-set属性存起来,待达到一定条件的时将data-img的属性值赋给src。
如下是通过scroll滚动事件监听来实现的图片懒加载,当图片都加载完毕移除事件监听,并且将移除html标签。
const lazyLoad=function(imgs){let count=0;const deleteImgs=[];const handler=()=>{imgs.forEach((img,index)=>{const react=img.getBoundingClientRect();if(react.top<window.innerHeight){img.src=dataset.src;count++;deleteImgs.push(index);if(count===imgs.length) document.removeEventListener('scroll',lazyLoad);}});imgs=imgs.filter((_,index)=>!deleteImgs.includes(index));}return handler();
}
scroll滚动事件容易造成性能问题。那可以通过 IntersectionObserver 自动观察img标签是否进入可视区域。
实例化 IntersectionObserver 实例,接受两个参数:callback是可见性变化时的回调函数,option是配置对象(该参数可选)。
当 img 标签进入可视区域时会执行实例化时的回调,同时给回调传入一个 entries 参数,保存着实例观察的所有元素的一些状态,比如每个元素的边界信息,当前元素对应的 DOM 节点,当前元素进入可视区域的比率,每当一个元素进入可视区域,将真正的图片赋值给当前 img 标签,同时解除对其的观察。
const lazyLoad=function(imgs){const observer=new IntersectionObserver((entries)=>{entries.forEach(entry=>{if(entry.intersectionRatio>0){entry.target.src=dataset.src;observer.unobserve(entry.target);}})})imgs.forEach(img=>observer.observe(img));
}
如上是懒加载图片的实现方式。
值得思考的是,懒加载和惰性函数有什么不一样嘛?
我所理解的懒加载顾名思义就是需要了才去加载,懒加载正是惰性的一种,但惰性函数不仅仅是懒加载,它还可以包含另外一种方向。
惰性函数的另一种方向是在重写函数,每一次调用函数的时候无需在做一些条件的判断,判断条件在初始化的时候执行一次就好了,即下次在同样的条件语句不需要再次判断了,比如在事件监听上的兼容
6、预加载
- 什么是预加载
资源预加载是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。预加载简单来说就是将所有所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源
- 为什么要用预加载
在网页全部加载之前,对一些主要内容进行加载,以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,直到所有内容加载完毕。
- 实现预加载的集中办法
使用html标签
<img src="http://pic26.nipic.com/20121213/6168183 0044449030002.jpg" style="display:none"/>
使用Image对象
<script src="./myPreload.js"></script>
//myPreload.js文件
var image= new Image()
image.src="http://pic26.nipic.com/20121213/6168183 004444903000 2.jpg"
使用XMLHttpRequest对象,虽然存在跨域问题,但会精细控制预加载过程
var xmlhttprequest=new XMLHttpRequest();
xmlhttprequest.onreadystatechange=callback;
xmlhttprequest.onprogress=progressCallback;
xmlhttprequest.open("GET","http://image.baidu.com/mouse,jpg",true);
xmlhttprequest.send();
function callback(){if(xmlhttprequest.readyState==4&& xmlhttprequest.status==200){var responseText=xmlhttprequest.responseText;}else{console.log("Request was unsuccessful:"+xmlhttprequest.status);}
}
function progressCallback(e){e=e || event;
if(e.lengthComputable){console.log("Received"+e.loaded+"of"+e.total+"bytes")
}
}
使用PreloadJS库
PreloadJS提供了一种预加载内容的一致方式,以便在HTML应用程序中使用。预加载可以使用HTML标签以及XHR来完成。默认情况下,PreloadJS会尝试使用XHR加载内容,因为它提供了对进度和完成事件的更好支持,但是由于跨域问题,使用基于标记的加载可能更好
//使用preload.js
var queue=new createjs.LoadQueue();//默认是xhr对象,如果是new createjs.LoadQueue(false)是指使用HTML标签,可以跨域
queue.on("complete",handleComplete,this);
queue.loadManifest([
{id:"myImage",src:"http://pic26.nipic.com/20121213/6168183 0044449030002.jpg"},
{id:"myImage2",src:"http://pic9.nipic.com/20100814/2839526 1931471581702.jpg"}
]);
function handleComplete(){var image=queue.getResuLt("myImage");document.body.appendChild(image);
}
- 懒加载和预加载的对比
两者都是提高页面性能有效的办法,两者主要区别是一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。
7、ES6中export和import
- export
export有2种导出模式
1、exoprt
2、export default [ 一个js模块只能有一个default ]
导出变量:
export 后边可以是一个变量声明表达式或者是一个{}里边包含变量名,但是不能直接输出一个变量, export default 后边可以直接跟一个常量或者变量,但是不能跟声明表达式
export var a = 1 //正确
const age = 100
export { age } //正确
export age //错误
export default age //正确
export default 50 //正确
export default var name='abc ' //错误
导出函数:
export和export都可以直接导出函数声明语句,但是export后边不能跟匿名函数,如果直接导出函数名export 需要用{}包裹
//正确export default function test () {console.log('test function')
}//正确export function test2 () {console.log('test function')
}
//错误export function () {console.log('test function')
}//正确export default function () {console.log('test function')
}function test3(){console.log('test3 function')
}//正确
expor {test3}
//正确
export default test3
错误
export test3
使用 as别名导出
let a = 100export {a as age }
- import 导入
对于使用export default 导出的,倒入时不需要使用{},且名字可以任意定义
对于使用export 导出的,必须使用{}倒入,且名字必须一致
可以使用通配符* 方式全部导入 (import * as obj from ‘…/a.js’)
//对于export default 导出的
import myFn from './a.js'//对于使用export 导出的
import {test1,test2} from './a.js'
- 按需加载
采用回调函数的方式,所有的引入直接在回调中
document.onclick = function() {import('./a.js').then(data => {console.log(data)})}
小结 - 模块化写法优点:
防止作用域污染
提高代码的复用性
降低维护成本
知识延伸:require 和 import的区别
导入require 导出 exports/module.exports 是 CommonJS 的标准,通常适用范围如 Node.js
import/export 是 ES6 的标准,通常适用范围如 React
require 是赋值过程并且是运行时才执行,也就是同步加载
require 可以理解为一个全局方法,因为它是一个方法所以意味着可以在任何地方执行
import 是解构过程并且是编译时执行,理解为异步加载
import 会提升到整个模块的头部,具有置顶性,但是建议写在文件的顶部
require和import的性能
require 的性能相对于 import 稍低。因为 require 是在运行时才引入模块并且还赋值给某个变量,而 import 只需要依据 import 中的接口在编译时引入指定模块所以性能稍高
二、css部分
1、遇到的问题小结
如果父组件没有些样式,style,则组件内部的背景颜色默认为透明色 transparent
如果要修改组件内部的背景颜色,可以直接这样设置
<conponent style="{background-color:#fff}">
如果页面内容高度不确定,可以给div盒子写高度,但是不需要写死高度,理由1:如果写死了高度,则当内容超出盒子高度后,超出部分无法正常显示;理由2:如果不写高度的话,背景或者盒子的高度则被被内容自动撑开,从而实现自适应的效果
1、如果盒子有内容,但是没有设置高度,则盒子会被内容自动撑开如果盒子有内容,设置我min-height,则会根据内容自动撑开如果盒子有内容,有设置高度height,如果内容小于height则正常在盒子内显示,其余会溢出盒子2、如果盒子没有内容,但是没有设置高度,则盒子是空白,就没有任何显示如果盒子没有内容,但是有设置min-height,则会按照min-height的高度进行显示如果盒子没有内容,有设置height,则会按照height的高度进行显示
文本过长,超出div宽度,怎么办?
css 样式调试语法注意事项
css样式无法生效的时候,可能是因为权重问题,可以设置 !important
/deep/ .el-checkbox { .el-checkbox__label{ color: #fff; } } /deep/ .el-checkbox.is-checked{ .el-checkbox__label{ color: #38FFF2!important; } }
- 如何引入在线iconfont
关于组件内部插槽样式如何编写的问题?
如果chrome控制台审查样式的时候,发现有一些样式并非自己写的,而是写着user agent style
css 样式选择器
- CSS字体图标 | 字体渐变如何实现?
background-image:-webkit-linear-gradient(bottom,red,#ff5f60,#f0c41b);
-webkit-background-clip:text;
-webkit-text-fill-color:transparent;
- height:100% & height:inherd 有何区别
当内容超出盒子的宽度或者高度的时候,如何设置滚动条、滚动槽
如何将页面手动滚动到最顶部?
通过scrollTop即可实现,获取dom元素,然后修改其scrollTop = 0;
2、web自适应方案
- 通过scss提供的函数
前端javascript常见问题总结相关推荐
- 在C#后端处理一些结果然传给前端Javascript或是jQuery
在C#后端处理一些结果然传给前端Javascript或是jQuery,以前Insus.NET有做过一个例子<把CS值传给JS使用 >http://www.cnblogs.com/insus ...
- Web前端-JavaScript基础教程上
Web前端-JavaScript基础教程 将放入菜单栏中,便于阅读! JavaScript是web前端开发的编程语言,大多数网站都使用到了JavaScript,所以我们要进行学习,JavaScript ...
- 判断字符串 正则_(重学前端 - JavaScript(模块一)) 14、引用类型之 RegExp (正则)(详述)...
上一篇文章介绍了 JavaScript 中的 Date 类型,从地理方面的原理知识开始入手,如果大家认真看过上一篇文章,相信 JavaScript 中的 Date 类型已经难不住大家了!!! 但是今天 ...
- vue.js 前端开发常见问题
前端开发常见问题 1. 热部署失效解决办法:参考 查看系统当前max_user_watches的值 $ cat /proc/sys/fs/inotify/max_user_watches 复制代码 应 ...
- 前端---JavaScript基础4
文章目录 前端---JavaScript基础3 call&apply 原型链 原型链操作 例子:按钮组件封装:(类似于Bootstrsp里的按钮组件封装) 前端-JavaScript基础3 c ...
- 前端---JavaScript基础3
文章目录 前端---JavaScript基础3 普通对象与函数对象 原型及属性判断 构造函数继承 原型继承 组合继承 寄生组合式继承 前端-JavaScript基础3 普通对象与函数对象 原型及属性判 ...
- 前端---JavaScript基础2
文章目录 前端---JavaScript基础2 对象类型判断 call函数 对象属性操作 深拷贝方法 前端-JavaScript基础2 重构以下代码:(以面向对象的方式) 重构后:(其中this指针问 ...
- 前端---JavaScript基础1
文章目录 前端---JavaScript基础1 数据类型 面向对象 对象创建方式 对象类型判断 前端-JavaScript基础1 JS是 解释型语言:跨平台 慢 编译型语言:不能跨平台 快 数据类型 ...
- web 前端 如何分享到instagram_好程序员web前端教程分享前端javascript练习题三
好程序员web前端教程分享前端javascript练习题三 cookie 一周内免登录 样式代码: 姓名: 密码: 一周内免登陆 js功能代码: var input=document.getEleme ...
最新文章
- C#中Delegate和Event以及它们的区别(转载)
- sping配置文件中引入properties文件方式
- 风云编程python-Python中*args 和**kwargs的用法
- 阿里云张献涛:一切从场景出发,实现计算的全场景覆盖
- 学妹问,学网站开发还是打 ACM?
- python 安装包时出现:SyntaxError: invalid syntax
- 海康威视网络摄像机连接、使用方法
- pe_xscan作了3点更新 1
- ASCⅡ码与字符的相互转化
- 杭州的互联网公司总结
- cdr 表格自动填充文字_长期伏案于表格,查看数据时你需要一个聚光灯效果
- 状语从句不是简单句_简单句、复合句Gloria总结
- webservice 菜鸟探索之旅
- 【BI学习笔记】在Linux上安装Wyn Enterprise商业智能报表服务器
- STM32F429 以太网MAC滤波应用说明
- Super VLAN概述
- Win RT再遭宏碁唱衰 微软被迫调整策略
- 2022年端边云协同的AI视觉产业研究报告
- 创业公司股份构成相关知识
- gym.error.DependencyNotInstalled: Found neither the ffmpeg nor avconv executables.
热门文章
- Android 9.0 wifi的随机mac地址修改为固定不变
- Android开发总结:个人开发者如何通过广告平台赚钱
- plt.scatter设置点大小_设置电脑桌面壁纸图文教程,下载图片设置计算机系统屏幕背景方法...
- 一条命令搞定黑苹果双系统时差
- 悲催的体能测试,需要休整的身体~
- 解决linux“嘟嘟”的报警声
- 大型数据库Oracle基础练习
- CF1677E Tokitsukaze and Beautiful Subsegments
- 【人月神话】第二章:人月神话
- 【脑洞大开】《西潮》及《走向世界丛书》