前端面试锦囊1

硬件面试话术锦囊问题-硬件和PCB 设计 本文针对硬件工程师面试中的PCB设计和电子元器件问题提供专业解答。PCB设计部分重点讲解高速信号走线、地平面设计、去耦滤波、信号完整性和EMI/EMC等关键技术,强调通过优化布局降低环路电感和辐射干扰。电子元器件部分详细解析放大器、反馈机制、振荡器、蓝牙技术等核心概念,特别强调仪表放大器的高输入阻抗、高共模抑制比等特性。文章还提供面试准备建议,包括电路设计原理掌握、实际案例分析和仿真能力展示,帮助应聘者系统展现专业能力。全文以工程实践为导向,突出硬件设计的实用技巧和关键参数考量。 阅读详情

css篇

px、rem、em的区别?
1、rem 和 em 单位是由浏览器基于你的设计中的字体大小计算得到的像素值,适用于响应式布局。
2、em 单位基于使用他们的元素的字体大小。
3、rem 单位基于 html 元素的字体大小。
4、em 单位可能受任何继承的父元素字体大小影响
5、rem 单位可以从浏览器字体设置中继承字体大小。
6、使用 em 单位应根据组件的字体大小而不是根元素的字体大小。
7、在不需要使用em单位,并且需要根据浏览器的字体大小设置缩放的情况下使用rem。
8、使用rem单位,除非你确定你需要 em 单位,包括对字体大小。
9、媒体查询中使用 rem 单位
10、不要在多列布局中使用 em 或 rem -改用 %。
11、不要使用 em 或 rem,如果缩放会不可避免地导致要打破布局元素。
12、px是固定的像素,一旦设置就无法因为适应页面大小而改变
CSS选择器有哪些?哪些属性可以继承?CSS优先级算法如何计算?
CSS选择符:id选择器(#myid)、类选择器(.myclassname)、标签选择器(div, h1, p)、相邻选择器(h1 + p)、子选择器(ul > li)、后代选择器(li a)、通配符选择器(*)、属性选择器(a[rel=”external”])、伪类选择器(a:hover, li:nth-child)
可继承的属性:font-size, font-family, color
不可继承的样式:border, padding, margin, width, height
优先级(就近原则):!important > [ id > class > tag ]
!important 比内联优先级高
CSS有哪些定位方式?他们分别有什么特点?
定位方式:相对定位、绝对定位、固定定位
relative 相对定位,相对定位不脱离文档流,参考其在原来文档流中的位置,通过 top,bottom,left,right 定位,并 且可以通过z-index进行层次分级。
• absolute 绝对定位,绝对定位脱离文档流,依据最近的已经定位(绝对、相对或固定定位)的父元素,通过 top,bottom,left,right 定位。当父级 position 为 static 时,absolute元素将依据body根元素(浏览器窗口)进行定 位,可以通过z-index进行层次分级。
• fixed 固定定位,固定定位与父元素无关(无论父元素是否定位),直接根据浏览器窗口定位,且不随滚动条拖动 页面而滚动,可通过z-index进行层次分级。
描述下盒子模型,他们有什么区别,使用什么属性去改变盒子模型?
标准盒子模型(content-box):宽度=内容的宽度(content)+border+padding+margin
IE盒子模型(border-box):宽度=内容宽度(content+border+padding)+margin
说出水平垂直居中方法(至少两种)

<div class=”box”></div>
.box{width:200px;height:400px;position:absolute;left:50%;top:50%;margin-left:-100px;margin-top:-200px;}
.box{width:200px;height:400px;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%;}
.box{width:200px;height:400px;position:absolute;left:0;top:0;right:0;bottom:0;margin:auto;}

页面布局方式(至少3种)
流体布局、圣杯布局、双飞翼布局、flex布局
请解释一下 CSS3 的 flexbox(弹性盒布局模型),以及适用场景?
该布局模型的目的是提供一种更加高效的方式来对容器中的条目进行布局、对齐和分配空间。在传统的布局方式中,block 布局是把块在垂直方向从上到下依次排列的;而 inline 布局则是在水平方向来排列。弹性盒布局并没有这样内在的方向限制,可以由开发人员自由操作。
试用场景:弹性布局适合于移动前端开发,在Android和ios上也完美支持。
为什么要初始化 CSS 样式?
因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。
CSS有哪些伪类样式?
p:first-of-type 选择属于其父元素的首个元素
p:last-of-type 选择属于其父元素的最后元素
p:only-of-type 选择属于其父元素唯一的元素
p:only-child 选择属于其父元素的唯一子元素
p:nth-child(2) 选择属于其父元素的第二个子元素
:enabled :disabled 表单控件的禁用状态。
:checked 单选框或复选框被选中。
列举HTML5新特性(至少5种)?
1、拖拽释放(Drap and drop) API ondrop
2、自定义属性data-id
3、语义化更好的内容标签(header,nav,footer ,aside, article, section)
4、地理(Geolocation) API
5、表单控件 calendar , date , time , email , url , search , tel , file , number
6、新的技术 webworker, websocket , Geolocation
列举Css3新特性
媒体查询、盒阴影、边框图片、字体属性、圆角边框、文字阴影、自定义动画、过渡、渐变
行级、块级元素有哪些,他们有什么区别?
行级:a span b em i input image select
块级:div h1~h6 ul li dd dt dl p table
区别:1. 块级元素会独占一行,其宽度自动填满其父元素宽度
行内元素不会独占一行,相邻的行内元素会排列到同一行里,直到一行排不下,才会换行,其宽度随元素的内容变化而变化,
2. 一般情况下,块级元素可以设置width,height属性,行内元素设置width,height无效(注意,块级元素设置了width宽度属性后仍然是独占一行的)
3. 块级元素可以设置margin,padding属性
行内元素的水平方向的padding-left和padding-right都会产生边距效果,但是竖直方向上的padding-top和padding-bottom都不会产生边距效果

隐藏元素的方式有哪些?
Display:none;overflow:hidden; visibility:hidden;
display:none 不显示对应的元素,在文档布局中不再分配空间(回流+重绘)
visibility:hidden 隐藏对应元素,在文档布局中仍保留原来的空间(重绘)

JS篇

JS的数据类型有哪些?
Undefined、null、boolean、number、string
常用的数组方法有哪些?
1.push()向数组的末尾添加新内容,返回新增后的数组长度,改变原数组
2.Pop()删除数组最后一项,返回被删除的项,改变原数组
3.Shift()删除数组的第一项,返回被删除的项,改变原数组
4.Unshift()向数组首位添加新的内容,返回新数组的长度,改变原数组
5.Slice()按条件查找出其中的部分内容,返回新数组,不改变原数组
array.slice(n, m),从索引n开始查找到m处(不包含m)
array.slice(n) 第二个参数省略,则一直查找到末尾
array.slice(0)原样输出内容,可以实现数组克隆
array.slice(-n,-m) slice支持负参数,从最后一项开始算起,-1为最后一项,-2为倒数第二项
6.Splice():对数组进行增删改,返回删除的新数组,原有数组改变
增加:ary.splice(n,0,m)从索引n开始删除0项,把m或者更多的内容插入到索引n的前面
返回空数组
修改:ary.splice(n,x,m)从索引n开始删除x个,m替换删除的部分
把原有内容删除掉,然后用新内容替换掉
删除:ary.splice(n,m) 从索引n开始删除m个内容
(如果第二个参数省略,则从n删除到末尾)
7.Join()用指定的分隔符将数组每一项拼接为字符串,返回拼接好的字符串,不改变原数组
8.Concat()用于连接两个或多个数组,返回连接后的新数组,不改变原数组
9.IndexOf()检测当前值在数组中第一次出现的位置索引,第一次查到的索引,未找到返回-1,不改变原数组
array.indexOf(item,start) item:查找的元素 start:字符串中开始检索的位置
10.forEach()循环遍历数组每一项,forEach中不能使用continue和break,forEach中不能跳出,只能跳过(return跳过)
函数 ary.forEach(function(item,index,ary){}) item:每一项 index:索引 ary:当前数组
常用的字符串方法有哪些?
1.charAt(index)通过index索引值查到对应的字符串
2.charCodeAt(index)是通过索引找到当前索引字符的ASCll码,如果没有,则返回NaN
3.indexOf(寻找的字符,【开始寻找的位置】)如果找到则返回当前字符的索引,找不到则返回 -1.第二个参数表示从那个索引位置开始 查找,如果是负数,说明从后往前数的第几位,(但是绝对值大于整个字符串的长度,则位置从头开始)
4.substring(indexStart,indexEnd)返回的是indexStart 开始到indexEnd结束的一个字符串,该字符串是原字符串的子集,包括开始位置,不包括结束位置
5.slice(beginIndex,endIndex)是beginIndex开始到endIndex结束的一个字符串,该字符串是原字符串的子集,包括开始位置,不包括结束位置
6.substr(start,length)返回一个字符串中从指定位置开始到指定字符数的字符。从start开始,截取length个
7.split()用来指定分隔符将字符串分割成一个字符串数组的方法,可以指定分割的字符,如果是个’ ',空字符串,默认和数组一样的格式,就是逗隔开
8.replace()返回由替换值替换部分或者所有的之后的新字符串,被替换的可以是个字符串,也可以是个正则表达式。替换值可以是一个或者多个字符串,如果选择被替换的是个字符串,则仅替换第一个匹配项
9.repeat(数字)构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本。里面的数字必须为正数,如果是小数,则默认取整
常用的对象方法有哪些?
1.hasOwnProperty():返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)
2.isPrototypeOf():用于测试一个对象是否存在于另一个对象的原型链上
3.toString():返回一个表示该对象的字符串
4.valueOf():返回指定对象的原始值
5.Object.assign():用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象
6.Object.create():创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。即创建一个以指定的对象为原型的子对象
7.Object.setPrototypeOf():设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或null
8.Object.getPrototypeOf():返回指定对象的原型(内部[[Prototype]]属性的值)
9.Object.defineProperties():直接在一个对象上定义新的属性或修改现有属性,并返回该对象
10.Object.defineProperty():会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象
11.Object.keys():会返回一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用for…in循环遍历该对象时返回的顺序一致 。
12.Object.values():返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for…in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )
13.Object.entries():返回一个给定对象自身可枚举属性的键值对数组,其排列与使用for…in循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)
14.Object.fromEntries():把键值对列表转换为一个对象,是Object.entries()的逆操作。
15.Object.is():判断两个值是否是相同的值
数组遍历方法有哪些?
1.forEach:遍历数组

var arr=[1,2,3,4,5]
for(var i=0;i<arr.length;i++){
console.log(arr[i])//1,2,3,4,5
}
arr.forEach(function(value,index){
console.log(value)//1,2,3,4,5
})

2.map:将数组映射成另一个数组,通过指定函数处理数组的每一个元素,并返回处理后的新数组

 var numbers = [1,2,3];
var doubledNumbers = [];
// es5写法
 for(var i = 0; i < numbers.length; i++){
 doubledNumbers.push(numbers[i] * 2);
 }
 console.log(doubledNumbers);//[2,4,6]

// es6 map方法
 var doubled = numbers.map(function(number){
   return number * 2;
 })
 console.log(doubled);//[2,4,6]

3.filter:从数组中找出所有符合指定条件的元素

//1.假定有一个对象数组(A),获取数组中指定类型的对象放到B数组中
var porducts = [
  {name:"cucumber",type:"vegetable"},
  {name:"banana",type:"fruit"},
  {name:"celery",type:"vegetable"},
  {name:"orange",type:"fruit"}
];
// es5写法
var filteredProducts = [];
for(var i = 0; i < porducts.length; i++){
    if(porducts[i].type === "vegetable"){
      filteredProducts.push(porducts[i]);
    }
}
console.log(filteredProducts);//[{name: "cucumber", type: "vegetable"},
                                 {name: "celery", type: "vegetable"}]
 // es6 filter
 var filtered2 = porducts.filter(function(product){
 return product.type === "vegetable";
})
console.log(filtered2);
//2假定有一个对象数组(A),过滤掉不满足以下条件的对象
//条件: 蔬菜 数量大于0,价格小于10
var products = [
  {name:"cucumber",type:"vegetable",quantity:0,price:1},
  {name:"banana",type:"fruit",quantity:10,price:16},
  {name:"celery",type:"vegetable",quantity:30,price:8},
  {name:"orange",type:"fruit",quantity:3,price:6}
];
products = products.filter(function(product){
    return product.type === "vegetable"
    && product.quantity > 0
    && product.price < 10
})
console.log(products);//[{name:"celery",type:"vegetable",quantity:30,price:8}]


//3.假定有两个数组(A,B),根据A中id值,过滤掉B数组不符合的数据
var post = {id:4,title:"Javascript"};
var comments = [
   {postId:4,content:"Angular4"},
   {postId:2,content:"Vue.js"},
   {postId:3,content:"Node.js"},
   {postId:4,content:"React.js"},
];
function commentsForPost(post,comments){
   return comments.filter(function(comment){
     return comment.postId === post.id;
   })
}
console.log(commentsForPost(post,comments));//[{postId:4,content:"Angular4"},{postId:4,content:"React.js"}]

4.find返回通过测试(函数内判断)的数组的第一个元素的值

//假定有一个对象数组(A),找到符合条件的对象
var users = [
  {name:"Jill"},
  {name:"Alex",id:2},
  {name:"Bill"},
  {name:"Alex"}
 ];
// es5方法
 var user;
 for(var i = 0; i < users.length; i++){
  if(users[i].name === "Alex"){
    user = users[i];
    break;//找到后就终止循环
  }
 }
 console.log(user);// {name:"Alex",id:2}
 // es6 find
 user = users.find(function(user){
   return user.name === "Alex";
 })
 console.log(user);// {name:"Alex",id:2}找到后就终止循环
 
//2.假定有一个对象数组(A),根据指定对象的条件找到数组中符合条件的对象
var posts = [
 {id:3,title:"Node.js"},
 {id:1,title:"React.js"}
];
var comment = {postId:1,content:"Hello World!"};
function postForComment(posts,comment){
 return posts.find(function(post){
   return post.id === comment.postId;
 })
}
console.log(postForComment(posts,comment));//{id: 1, title: "React.js"}

5、every && some
every:数组中是否每个元素都满足指定的条件
some:数组中是否有元素满足指定的条件
总而言之:Some: 一真即真;Every: 一假即假

//ES6 some every
var every = computers.every(function(computer){
  return computer.ram > 16;
})
console.log(every);//false
var some = computers.some(function(computer){
 return computer.ram > 16;
})
console.log(some);//true

6.reduce:接收一个方法作为累加器,数组中的每个值(从左至右) 开始合并,最终为一个值

// 计算数组中所有值的总和
var numbers = [10,20,30];
 var sum = 0;
//es5 方法
for(var i = 0; i < numbers.length; i++){
  sum += numbers[i];
}
console.log(sum);
 // es6 reduce
var sumValue = numbers.reduce(function(sum2,number2){
 console.log(sum2);//0 10 30 60
 return sum2 + number2;
},0);//sum2初始值为0
console.log(sumValue);
//将数组中对象的某个属性抽离到另外一个数组中
var primaryColors = [
   {color:"red"},
   {color:"yellow"},
   {color:"blue"}
 ];
 var colors = primaryColors.reduce(function(previous,primaryColor){
    previous.push(primaryColor.color);
    return previous;
 },[]);
 console.log(colors);//["red", "yellow", "blue"]

对象遍历方法有哪些?
遍历对象所有的可枚举属性(自有的+继承的属性),使用 for…in
遍历对象自有的所有可枚举属性(非继承属性),使用 Object.keys() 或 for…in + Objec.hasOwnProperty()
获取对象所有继承属性(非自有属性),可以使用 for…in + Object.keys()
遍历对象自有的所有可枚举和不可枚举属性(非继承属性),使用 Object.getOwnPropertyNames()
获取对象自有的所有可枚举、不可枚举属性和继承属性,使用 for…in + Object.getOwnPropertyNames(obj) 或 for…in + Object.keys() + Object.getOwnPropertyNames(obj)
JS转数据类型方法有哪些?
使用转换函数、强制类型转换、利用js变量弱类型特性进行转换
Number()转换数值,string转换字符串,boolean转换布尔类型
undefined,null 和 undeclared 有什么区别?
a、null表示"没有对象",即该处不应该有值,转为数值时为0。典型用法是:作为函数的参数,表示该函数的参数不是对象。作为对象原型链的终点。
b、undefined表示"缺少值",就是此处应该有一个值,但是还没有定义,转为数值时为NaN。典型用法是:变量被声明了,但没有赋值时,就等于undefined。调用函数时,应该提供的参数没有提供,该参数等于undefined。对象没有赋值的属性,该属性的 值为undefined。函数没有返回值时,默认返回undefined。
c、undeclared:js语法错误,没有申明直接使用,js无法找到对应的上下文。
new操作符具体干了什么呢?
1.创建一个空对象

let obj=new Object();

2.链接到原型
把obj的proto指向构造函数Func的原型对象prototype,此时便建立了obj对象的原型链:obj->Func.prototype->Object.prototype->null

obj.__proto__=Func.prototype;

3.绑定this值(让Func中的this指向obj,并执行Func的函数体)

let result=Func.call(obj);

4.返回新对象(判断Func的返回值类型:如果无返回值或者返回一个非对象值,则将obj作为新对象返回;否则会将result作为新对象返回)

if(typeof(result)=="object"){
func=result;
}else{
func=obj;
}

至少3种用JS跳转页面的方法?

//1.指定调转的地方
window.location.href='url'
//2.参见的浏览器返回上一个已访问的页面,直到访问最初访问的页面
window.history.back(-1);
//3.navigate对象包含有关浏览器的信息,也可以作为页面跳转,后面直接加要跳转的地方
window.navigate("url")
//4.当页面内有框架时,指定最顶层的窗口跳转,以及包含框架的最外层的浏览器
top.location="url"

怎么获取浏览器窗口的可视高度?

alert($(window).height()); //浏览器时下窗口可视区域高度

alert($(document).height()); //浏览器时下窗口文档的高度
alert($(document.body).height());//浏览器时下窗口文档body的高度
alert($(document.body).outerHeight(true));//浏览器时下窗口文档body的总高度 包括border padding margin
alert($(window).width()); //浏览器时下窗口可视区域宽度
alert($(document).width());//浏览器时下窗口文档对于象宽度
alert($(document.body).width());//浏览器时下窗口文档body的高度
alert($(document.body).outerWidth(true));//浏览器时下窗口文档body的总宽度 包括border padding margin
 
alert($(document).scrollTop()); //获取滚动条到顶部的垂直高度
alert($(document).scrollLeft()); //获取滚动条到左边的垂直宽度

什么是事件委托?
事件委托也称之为事件代理(Event Delegation)。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡
一个事件触发后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段。
(1)捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会响应任何事件;
(2)目标阶段:在目标节点上触发,称为“目标阶段”
(3)冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层。
如何在JS中编码和解码 URL
escape 和 unescape
*escape()*不能直接用于URL编码,除了ASCII字母、数字、标点符号"@ * _ + - . /“以外,对其他所有字符进行编码,它的真正作用是返回一个字符的Unicode编码值.对应的解码函数是unescape()。
注意点:
Javascipt函数的输入和输出,默认都是Unicode字符
*escape()*不对”+“编码,服务器处理数据的时候,会把+号处理成空格
encodeURI 和 decodeURI
它着眼于对整个URL进行编码,因此除了常见的符号以外,对其他一些在网址中有特殊含义的符号”; / ? : @ & = + $ , #“,也不进行编码。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。
它对应的解码函数是decodeURI()
encodeURIComponent 和decodeURIComponent
它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。
因此,”; / ? : @ & = + $ , #",这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码。至于具体的编码方法,两者是一样。
前端存储有哪些、特点、项目中应用场景?
存储方式:cookie,sessionStorage,localStaorage,indexedDB

COOKIE常用属性:
Expires 用于设置 Cookie 的过期时间
Max-Age 用于设置在 Cookie 失效之前需要经过的秒数(优先级比Expires高)
Domain指定了 Cookie 可以送达的主机名
Path指定了一个 URL路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部
区别:
cookie在浏览器和服务器间来回传递。sessionStorage和localStorage不会;
sessionStorage和localStorage的存储空间更大;
sessionStorage和localStorage有更多丰富易用的接口;
sessionStorage和localStorage各自独立的存储空间;
cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。
cookie数据始终在同源的http请求中携带(即使不需要),即会在浏览器和服务器间来回传递。
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存
有效时间:
localStorage:存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage:数据在当前浏览器窗口关闭后自动删除
cookie:设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

localstorage存储:只能存入字符串,无法直接存对象
设置:localStorage.setItem(‘Name’,‘value’);
获取:localStorage.getItem(‘Name’);
获取键名:localStorage.key(0);
删除:localStorage.removeItem(‘Name’)
一次性清除所有存储:localStorage.clear();
session:会话关闭,消息移除
应用场景:
1、标记用户与跟踪用户行为的情况,推荐使用cookie
2、适合长期保存在本地的数据(令牌),推荐使用localStorage
3、敏感账号一次性登录,推荐使用sessionStorage
4、存储大量数据的情况、在线文档(富文本编辑器)保存编辑历史的情况,推荐使用indexedDB
对闭包的看法,为什么要用闭包?说一下闭包原理以及应用场景?
闭包是有权访问另一个函数私有变量的函数叫闭包。
使用闭包,一可以读取函数中的变量,二可以将函数中的变量存储在内存中,保护变量不被污染。而正因闭包会把函数中的变量值存储在内存中,会对内存有消耗,所以不能滥用闭包,否则会影响网页性能,造成内存泄漏。当不需要使用闭包时,要及时释放内存,可将内层函数对象的变量赋值为null。
闭包原理:
函数执行分成两个阶段(预编译阶段和执行阶段)。
在预编译阶段,如果发现内部函数使用了外部函数的变量,则会在内存中创建一个“闭包”对象并保存对应变量值,如果已存在“闭包”,则只需要增加对应属性值即可。
执行完后,函数执行上下文会被销毁,函数对“闭包”对象的引用也会被销毁,但其内部函数还持用该“闭包”的引用,所以内部函数可以继续使用“外部函数”中的变量
利用了函数作用域链的特性,一个函数内部定义的函数会将包含外部函数的活动对象添加到它的作用域链中,函数执行完毕,其执行作用域链销毁,但因内部函数的作用域链仍然在引用这个活动对象,所以其活动对象不会被销毁,直到内部函数被烧毁后才被销毁。
优点:
1.可以从内部函数访问外部函数的作用域中的变量,且访问到的变量长期驻扎在内存中,可供之后使用
2.避免变量污染全局
3.把变量存到独立的作用域,作为私有成员存在
缺点:
1.对内存消耗有负面影响。因内部函数保存了对外部变量的引用,导致无法被垃圾回收,增大内存使用量,所以使用不当会导致内存泄漏
2.对处理速度具有负面影响。闭包的层级决定了引用的外部变量在查找时经过的作用域链长度
3.可能获取到意外的值(captured value)
应用场景:
应用场景一: 典型应用是模块封装,在各模块规范出现之前,都是用这样的方式防止变量污染全局

var Test = (function () {
    // 这样声明为模块私有变量,外界无法直接访问
    var foo = 0;

    function Test() {}
    Test.prototype.bar = function bar() {
        return foo;
    };
    return Test;
}());

应用场景二: 在循环中创建闭包,防止取到意外的值

//如下代码,无论哪个元素触发事件,都会弹出 3。因为函数执行后引用的 i 是同一个,而 i 在循环结束后就是 3
for (var i = 0; i < 3; i++) {
    document.getElementById('id' + i).onfocus = function() {
      alert(i);
    };
}
//可用闭包解决
function makeCallback(num) {
  return function() {
    alert(num);
  };
}
for (var i = 0; i < 3; i++) {
    document.getElementById('id' + i).onfocus = makeCallback(i);
}

原型链?
理解原型和原型链首先要知道几个概念:
①、在js里,继承机制是原型继承。继承的起点是 对象的原型(Object prototype)。
②、一切皆为对象,只要是对象,就会有 proto 属性,该属性存储了指向其构造的指针。
Object prototype也是对象,其 proto 指向null。
③、对象分为两种:函数对象和普通对象,只有函数对象拥有『原型』对象(prototype)。
prototype的本质是普通对象。
Function prototype比较特殊,是没有prototype的函数对象。
new操作得到的对象是普通对象。
④、当调取一个对象的属性时,会先在本身查找,若无,就根据 proto 找到构造原型,若无,继续往上找。最后会到达顶层Object prototype,它的 proto 指向null,均无结果则返回undefined,结束。
⑤、由 proto 串起的路径就是『原型链』。
总结:
第一句话:prototype是函数的原型对象,即prototype是一个对象,它会被对应的__proto__引用。
第二句话:要知道自己的__proto__引用了哪个prototype,只需要看看是哪个构造函数构造了你,那你的__proto__就是那个构造函数的prototype。
第三句话:所有的构造函数的原型链最后都会引用Object构造函数的原型,即可以理解Object构造函数的原型是所有原型链的最底层,即Object.prototype.__proto===null
怎么理解this的指向?怎么改变this的指向?
this指向:
1、通常在函数中的 this 指向的是调用函数的那个对象(谁调用指向谁)
2、事件函数中的 this 通常指向的是绑定事件的事件源元素
3、构造函数中的 this ,(使用 new 调用构造函数创建对象),通常指向的是 new 所创建出来的对象本身
4、全局范围的 this 通常指向的是全局对象(浏览器中是 window)
修改this指向:

Function.prototype.bind(thisArg) -- ES5
//能够返回一个新函数,该新函数的主体与原函数主体一致,但当新函数被调用执行时,函数体中的 this 指向的是 thisArg 所表示的对象

Function.prototype.call(thisArg, val1, val2, ....)
//调用函数执行,在函数执行时将函数体中的 this 指向修改为 thisArg 所表示的对象
//val1, val2, .... 表示传递给调用函数的实际参数列表

Function.prototype.apply(thisArg, array|arguments)
//调用函数执行,在函数执行时将函数体中的 this 指向修改为 thisArg 所表示的对象,
//array|arguments 表示调用函数的参数列表,使用数组或类数组的格式

如何区分变量是数组还是对象?
方法一:通过判断变量的类型,并且变量的length属性(除了有一种例外是arguments对象–当给函数传参时数据存储的地方)
方法二:使用toString方法将对象转换成其他类型的string
方法三:ECMAScript 5中可以使用isArray来判断
方法四:使用isPrototypeOf()函数
原理:检测一个对象是否是Array的原型(或处于原型链中,不但可检测直接父对象,还可检测整个原型链上的所有父对象)
使用方法: parent.isPrototypeOf(child)来检测parent是否为child的原型;
需注意的是isPrototypeOf()函数实现的功能和instancof运算符非常类似;
方法五:使用constructor属性
方法六:使用concat方法–灵活变通
array.concat(数组1,数组2,…)
返回一个新数组,这个新数组是由两个或更多数组组合而成的
ECMAScript 2015(ES6)有哪些新特性?
箭头操作符 =>;
对类class的支持(constructor构造函数);
不定参数…x;let和const关键字;
for of遍历;
模块的支持import;
解构赋值;
展开(…)运算符
promise异步函数的处理模式(pending等待中;resolve返回成功,reject返回失败);
介绍下 Set、Map的区别?
1.Map是键值对,Set是值得集合,当然键和值可以是任何的值;
2.Map可以通过get方法获取值,而set不能因为它只有值;
3.都能通过迭代器进行for…of遍历;
4.Set的值是唯一的可以做数组去重,Map由于没有格式限制,可以做数据存储;

Map:Map对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。构造函数Map可以接受一个数组作为参数。

map对应的数据类型是对象{},它拥有和对象一样的方法;
map的键和值可以是任何对象,这一点对象的键只能是number或者string;
自带iterator遍历器,可以进行for...of遍历;
初始化一个Map: var map = new Map([[1],[2]]);
对应的方法:
size:返回Map对象中所包含的键值对个数
set(key, val): 向Map中添加新元素
get(key): 通过键值查找特定的数值并返回
has(key): 判断Map对象中是否有Key所对应的值,有返回true,否则返回false
delete(key): 通过键值从Map中移除对应的数据
clear(): 将这个Map中的所有元素删除
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
Set:Set对象允许你存储任何类型的值,无论是原始值或者是对象引用。它类似于数组,但是成员的值都是唯一的,没有重复的值。

set对应的数据类型是数据,有一些方法可以公用;
由于map是值的集合,所有set的键和值是相等的;
set所有的值是唯一的,可以进行数组去重;
自带iterator遍历器,可以进行for...of遍历;
初始化一个Set:var set = new Set(['1',undefined,{},2,[3,4]]);
对象的方法:
size:返回Map对象中所包含的键值对个数
add(value):添加某个值,返回 Set 结构本身(可以链式调用)。
delete(value):删除某个值,删除成功返回true,否则返回false。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。
keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回键值对的遍历器。
forEach():使用回调函数遍历每个成员。

如何取一个1~10的随机数
var num=Math.floor(Math.random()*10+1);
使用async、await如何捕获异常?
引入async、await,便于异步编程
async、await避免了js的回调地狱问题

 //async:作为一个关键字放到函数前面,用于表示函数是一个异步函数,异步函数意味着该函数的执行不会阻塞后面代码的运行
   // await表示等待,后面可以放任何表达式,不过更多的是放一个返回promise对象的表达式(async和await需一起使用)
//例如:
// 角色的编辑
    async editRole(id) {
      // 数据回显
      this.roleForm = await getRoleDetail(id)
      // 弹窗出现
      this.showDialog = true
    }
   //代码解析:在代码的执行过程中,调用editRole函数,在里面遇到了await,await表示等一下,于是代码就在这里暂停一下,不在向下执行,等待后面的promise对象执行完毕,拿到它的返回值之后,赋值给this.roleForm,暂停结束,代码继续执行,弹窗出现
    //异常的处理:通过try/catch捕获异常,把await放到try中进行执行,如有异常,就使用catch进行处理
//例如:
// 删除员工
    async deleteEmployee(id) {
      try {
        await this.$confirm('您确定删除该员工吗')
        await delEmployee(id)
        this.getEmployeeList()
        this.$message.success('删除员工成功')
      } catch (error) {
        console.log(error)
      }
    }

错误处理:
使用 promises 的情况下,一个异步函数会返回两种可能的值:resolved 和 rejected。我们可以使用 .then() 来处理正常的情况 .catch() 处理异常情况。
使用async/await的情况下,则使用try…catch,当 await 一个函数调用的时候,任何 rejected 的值都会以异常的形式抛出来
var、let、const区别
var定义的变量可以修改,如果不初始化会输出undefined,不会报错。
const定义的变量不可以修改,而且必须初始化。不然报错。
let是块级作用域,函数内部使用let定义后,对函数外部无影响。

// const k; // 报错
const k = 100;
// const k = 200; // 报错
var i = 99;

function test() {
    // console.log(i); // 报错
    let i = 10;
    console.log(i);
}
test() // 10 
console.log(i) //99

如何获取对象的key名?
使用for in遍历对象时,需要用hasOwnProperty(key)方法过滤掉非对象自身的属性(继承自原型链的属性)

var obj = {
  "name" : "suyan",
  "age" : 24,
}
for(var key in obj){  //遍历对象的所有属性,包括原型链上的所有属性
  if(obj.hasOwnProperty(key){ //判断是否是对象自身的属性,而不包含继承自原型链上的属性
    console.log(key);        //键名"name","age"
    console.log(arr[key]);   //键值"suyan",24
     }
}

什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的IE
响应式设计就是网站能够兼容多个终端,而不是为每个终端做一个特定的版本
基本原理是利用CSS3媒体查询,为不同尺寸的设备适配不同样式
对于低版本的IE,可采用JS获取屏幕宽度,然后通过resize方法来实现兼容:

$(window).resize(function () {
  screenRespond();
});
screenRespond();
function screenRespond(){
var screenWidth = $(window).width();
if(screenWidth <= 1800){
  $("body").attr("class", "w1800");
}
if(screenWidth <= 1400){
  $("body").attr("class", "w1400");
}
if(screenWidth > 1800){
  $("body").attr("class", "");
}
}

面向对象和面向过程的理解?
1.面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
2.面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
3.面向对象是以功能来划分问题,而不是步骤:基本思想是使用对象,类,继承,封装等基本概念来进行程序设计
说说Typescripy和Javascript的区别?
JavaScript是一种弱类型语言动态类型,弱类型语言多余小项目来说比较灵活,但是对于大项目来说,过于灵活会增加项目的复杂度,程序员维护起来比较困难
Typescript语言则是JavaScript的超集
可以编译成JavaScript执行,他的最大特点就是支持强类型,有编译类型检查,这为程序员编写程序带来了极大方便
JavaScript和Typescript的区别
typescript完全兼容javascript,它可以编译成javascript
typescript有编译时类型检查,这为程序的编写带来了极大的方便
javascript是一门动态语言,而typescript添加了可选的静态类型
typescript在javascript的基础上增加了不少特性

Typescript有哪些基础类型?

原始数据类型有以下六种:

boolean 布尔值
number 数值
string 字符串
null 空值
undefined 未定义
Symbol (ES6 中的新类型)

非原始数据类型有以下九种:

数组
Tuple 元祖
enum 枚举
never 永不存在的值的类型
void
any 任意类型
联合类型
函数类型
【Flow3D实战】从零构建水利冲淤模型:关键步骤与参数详解 本文详细介绍了使用Flow3D构建水利冲淤模型的关键步骤与参数设置技巧。从基础认知到前处理、计算设置和后处理,全面解析如何高效模拟水流与泥沙的相互作用,特别适用于桥墩冲刷、水库泄洪等工程场景。通过实战案例分享,帮助读者掌握Flow3D在水利工程中的精准应用,提升模型精度与计算效率。 阅读详情

相关推荐

从零搭建宝兰德BES单机版:分离式安装、环境变量配置到控制台访问的避坑指南

本文详细介绍了从零搭建宝兰德BES单机版的完整流程,包括分离式安装、环境变量配置和控制台访问的避坑指南。针对中间件安装部署中的常见问题,提供了账号规划、JDK配置、实例创建和防火墙设置等实用解决方案,帮助开发者和运维人员高效完成BES中间件的部署工作。

weixin_32576389的博客 371

前端面试题-1

cookie是服务器返回的,指定了expiretime(有效期)的是持久cookie,没有指定的是会话cookiewatch:是可以监听data属性中数据的变化、还可以被用来监听路由router的变化computed:computed属性的作用与watch类似,也可以监听属性的变化;属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算,主要当作属性来使用。动态路由的创建,主要是使用path属性过程中,使用动态路径参数,以冒号开头。

qq_38606923的博客 167

一文看懂分布式存储架构

目录一、集中存储结构二、分布式存储1 、分布式存储的兴起2 、分布式存储的重要性3 、分布式存储的种类和比较三、分布式理论浅析1 、一致性和可用性2 、数据分布3 、复制4 、分布式协议5、跨机房部署四、分布式文件系统1、 Google 文件系统( GFS )2、 Taobao 文件系统( TFS )3、 Fackbook Haystack 文件系统4、 CDN 内容分发网络五、分布式键值系统1、 Amazon Dynamo2、 Taobao Tiar3、 ETCD4 、产品选型比较( Etcd , Zoo

weixin_70730532的博客 2万+

前端中rem和em的区别,分别如何使用

前端中rem和em的区别,分别如何使用

admire_fish的博客 883

保姆级教程:用达芬奇Configurator配置CAN总线(从DBC导入到Controller设置)

本文详细介绍了使用达芬奇Configurator工具从DBC文件导入到CAN总线控制器设置的全流程配置方法。通过环境准备、CAN控制器模式选择、硬件参数配置、通信参数优化及通信栈集成等关键步骤,帮助开发者高效完成AUTOSAR架构下的CAN总线开发,特别适合汽车电子领域的工程师参考。

weixin_30529023的博客 440

Ubuntu Server 22.04.5系统安装教程

该教程主要是演示在服务器上安装Ubuntu server 22.04系统的详细步骤,主要包含,安装系统前的准备(镜像的下载,启动盘的制作),安装系统时的语言选择,网络设置,切换镜像源(可根据实际需求来配置,本文使用清华镜像源),手动分区,用户设置,ssh服务安装等。以上就是关于Ubuntu Server 22.04系统安装的详细过程。

逆水行舟,不进则退。 7759

px、em、rem,前端经典面试

所有未经调整的浏览器默认字体都是16px,

m0_60707660的博客 983

完整的申请邓白氏编码的流程(手把手教你申请邓白氏编码)

申请公司的苹果开发者账号和企业级的苹果开发者账号时,都会用到邓白氏编码,也就是我们申请苹果开发者账号时需要填写的D-U-N-S Number。     申请这个邓白氏编码是免费的,但是从像华夏邓白氏公司提交申请到可以申请苹果开发者账号来用这个9位的D-U-N-S Number,需要一段时间,我申请得到D-U-N-S Number,用了8个工作日(不算周末哦)

wxw2011014003的博客 9万+

【前端面经】百度二面

Q:手撕代码,arr=[{age:18, name: ‘lily’},{age:91, name: ‘andy’},{age:38, name: ‘tony’}],请按age排序写一个函数,再按name排序写一个函数。Q:css中position有哪些类型。Q:移动端rem和px是如何换算的,如果要实现根rem动态跟随屏幕大小变换应该如何实现。Q:手撕代码,12345678如何转换成12,345,678的逗号形式数据。Q:手撕代码,class EventBus如何实现。Q:vue中数据传递方式有哪些。

Lifelong learning. 391

[Dify实战]插件编写- 如何让插件直接输出文件对象(支持 TXT、Excel 等)

本文介绍了在Dify插件中实现文件对象返回的方法。通过create_blob_message()函数,开发者可以输出txt、Excel等格式文件,让用户直接下载而非复制文本。文章详细讲解了二进制文件生成的原理,提供了文本翻译和Excel报表生成的代码示例,并列出常见MIME类型对照表。这种技术能显著提升插件实用性,特别适用于翻译、报表生成等需要文件输出的场景,使交互体验从"复制粘贴"升级为"一键下载"。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 1246

ThingsBoard3.9.1规则引擎方式发送钉钉通知消息

thingsboard3.9.1/4.0规则链方式发送钉钉通知消息。

hssjf的专栏 530

前端面试题-rem 原理

前端面试题-rem原理

m0_46165310的博客 2693

【视频】GStreamer+WebRTC(九):使用NVIDIA硬编解码

2)下载 GStreamer-bad 插件包源码注意要下载和 GStreamer版本对应的插件包3)下载NVIDIA硬编解码SDK最新的SDK下载地址注意 GStreamer 1.24.2 中调用的 NVIDIA Video_Codec_SDK 不是最新的,先使用下面的方法,查看gst-plugins-bad-1.24.2.tar.xz 对应的NVIDIA Video_Codec_SDK 的版本是多少。

郭老二 260

面试锦囊

包装类型和基本类型区别 基本类型:字符,布尔,数值类型 byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。 short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。 int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。 long:64位,最大数据存储容量是2的64次方减1,数据范

不会英语的程序员不是好开拓者 332

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

前端面试锦囊

1.判断一个字符串是否由重复的字符串组成 2.计算2的n次幂 3.简单计算器 4.vue的数据的双向绑定原理: 数据监听 数据劫持 发布者/订阅者模式 Object.defineProperty()方法 5.数组的常见操作:添加元素 删除元素 修改元素 获取元素 添加元素:arr.push()末尾 arr.unshift()首位 arr.splice(1,0,“a”)在索引为1的位置增加元素a 删除元素:arr.pop()末尾 arr.shift()首位 arr.splice(5,3)任意位置 删除索引为

qq_40409143的博客 172

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

66个包过面试锦囊,拿走不谢!

点击蓝色关注,回复“职级”获取知名互联网公司职级定义每月开展上个月读者阅读、转发、在看、留言各前三名(冠、亚、季军)评选活动,次月初开奖!欢迎参加,有惊喜。如今疫情缓解,春意盎然,又到...

chengjun_java的专栏 915

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

66 个包过面试锦囊,拿走不谢!

点击关注上方“五分钟学算法”,设为“置顶或星标”,第一时间送达干货。转自军哥手记,作者程军哥如今疫情缓解,春意盎然,又到了金三银四的跳槽季节,很明显今年来的晚了一些。有的时候你会发现面...

程序员吴师兄的博客 677

java面试锦囊

目录 一 数据库MySql如何优化的? Sql语句的优化 你使用SpringBoot的时候各种配置文件是怎么引入的 说说你做过的项目和你主要负责的模块 讲讲Redis,你在项目中有用过Redis吗? 数据库建表的时候int(1)和int(2)的区别 二 #和$的区别 Springmvc的执行流程 Jvm参数 反射的三种创建方式 Arraylist和linklist的区别 Arraylist一次扩容多少 Vector是如何实现的安全的 讲讲你知道哪些排序方法,并说下他们的时

m0_47674540的博客 1470

前端面试锦囊2

笔试篇 1.使用CSS实现一个三角形 /* 把上、左、右三条边隐藏掉(颜色设为 transparent) */ #demo { width: 0; height: 0; border-width: 20px; border-style: solid; border-color: transparent transparent red transparent;} 2.使用CSS实现一个轮播图 <div class="slide"> <ul class="slide-

qq_41277458的博客 392

中osblock指的是什么_JavaScript中的this指的是什么?(面试锦囊)

如果大家接触到的编程语言足够多的话可以发现几乎在大部分编程语言里边都有this关键字,恐怕最难理解的要属于JavaScript中的this了。不同的环境this不同,不同的对象this不同。一般在前端的面试过程中面试官会问this是什么,可能很多小伙伴都会被问到,可能有些人会说this指的window对象,或者是实例对象。也有一些其他的。今天我们就来说下JavaScript中的this指的是什么?...

weixin_42503008的博客 118

4月前端幸存指南:如何让面试官在场景追问环节瞳孔地震(附脑图模板)

最近在面试地狱模式里连轴转,每天2-3场车轮战,面到第10天突然开窍——现在徒手撕框架源码都能带解说!但真正让我后背发凉的,是今年前端面试的隐形攻防战:一面八股文只是入场券,二面场景题才是绞肉机。突击检查了30+前端岗的面经,发现致命规律:一面还在问Diff算法实现,二面直接甩出"高并发场景下如何设计前端缓存策略"。面试官甚至会把你的项目流水线拆解重组,追问"如果让你用微前端重构这个系统,哪些模块会埋雷?

Perback的博客 1163

字节跳动春招攻略:学长学姐笔经面经,还有出题人「锦囊」

正在参加春季校招的同学们,此刻可能是最紧张的了: 简历投出去了,什么时候才能收到笔试通知啊? 收到了笔试通知,最后两天还来得及做什么准备? 面试会问什么问题?怎么才能提升通过率、拿到更好的offer? 不妨先来听一听过来人的故事。 我们找到了通过校招入职字节跳动的算法、后端、客户端、前端、大数据、测试方向的6位技术同学,分享他们校招中遇到的难题和拿到offer的独家秘笈。 来一起看看他们是如何过关斩将,拿到字节跳动offer的吧。 图形算法o...

字节跳动技术范儿 4406

ondestroy什么时候调用_JavaScript中的this指的是什么?(面试锦囊)

如果大家接触到的编程语言足够多的话可以发现几乎在大部分编程语言里边都有this关键字,恐怕最难理解的要属于JavaScript中的this了。不同的环境this不同,不同的对象this不同。一般在前端的面试过程中面试官会问this是什么,可能很多小伙伴都会被问到,可能有些人会说this指的window对象,或者是实例对象。也有一些其他的。今天我们就来说下JavaScript中的this指的是什么?...

weixin_39805529的博客 170

前端面试实战:技术深度与表达策略

前端开发领域的技术面试正逐渐从基础语法考察转向综合能力评估,尤其注重候选人对框架原理、浏览器工作机制等底层知识的掌握程度。Virtual DOM diff算法、React Fiber架构等核心概念的理解深度,往往通过性能优化、内存管理等工程实践来验证。在HTTP/2多路复用、Web Worker通信开销等具体场景中,技术决策能力比单纯编码更重要。优秀的前端工程师需要建立源码阅读、算法映射设计模式等系统化学习方法,同时掌握STAR-L叙事框架等技术表达策略,将项目经验转化为可量化的技术价值。本文通过前端面试的

weixin_30621711的博客 336

JAVA面试锦囊(六)

● 简单介绍一下MVC模式?MVC全名是Model View Controller,是模型(model) -- 视图(view) -- 控制器(controller)的缩写。一种...

ZeJava的博客 185
上一篇: 提高vue的配置分享
下一篇: 前端面试锦囊2
小小布灵鸟
博客等级 码龄9年 8粉丝 23原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值