前端面试十连问

  • 什么是闭包?闭包的用途是什么?闭包的缺点是什么?
    定义:闭包是函数和函数内部能访问到的变量的总和。
    具体实现:在函数A中声明了函数B,并在函数B中使用了A内部的局部变量或形参,函数B以返回值或对象属性的形式能够在函数A的外部继续调用。
    用途:(1)保存临时状态,在循环和定时器中可以使用当时的状态;(2)用来“封装”一些数据,如f1外部可以使用f1的内部数据,但不能直接通过f1.a获取。
    缺点:1.常驻内存,增加内存使用量;2.在IE中使用不当可能造成内存泄漏。
let fa=function(){
let a=1;
let fb=function(){console.log(a)}
window.fb=fb;
}
fa();  //调用f1将f2挂在window上
window.fb();  //结果为1,在f1外调用f2,打印出f1的局部变量a
  • call、apply、bind 的用法分别是什么?
    假设要调用对象x的fn函数,args为参数数组.
fn.call(x,...args)
 fn.apply(x,args)
fn.bind(x,args)()

区别在于call和apply是立即执行的,而bind只是赋值生成一个新函数,需要手动调用执行。

  • 请说出至少 10 个 HTTP 状态码,并描述各状态码的意义。
    https://blog.csdn.net/qq_40029828/article/details/109010005

  • 著名面试题:
    如何实现数组去重?
    假设有数组 array = [1,5,2,3,4,2,3,1,3,4]
    你要写一个函数 unique,使得
    unique(array) 的值为 [1,5,2,3,4]
    也就是把重复的值都去掉,只保留不重复的值。
    要求写出两个答案:
    一个答案不使用 Set 实现(6分)
    另一个答案使用 Set (4分)
    (附加分)使用了 Map / WeakMap 以支持对象去重的,额外加 5 分。
    说出每个方案缺点的,再额外每个方案加 2 分。

let  unique=function(array){
let array1=[];
for(let i=0;i<array.length;i++){
if(array1.indexof(array[i])===-1){array1.push(array[i])}
}
return array1
}  //不用Set
let  unique=function(array){
 let array1=new Set()
for(let i=0;i<array.length;i++){array1.add(array[i])}
return Array.from(array1)
}//使用Set
let  unique=function(array){
let map = new Map();
  let array1 = new Array();  
  for (let i = 0; i < array.length; i++) {
    if(!map.has(array[i])) { // 如果没有该key值
      array1.push(array[i]);
      map.set(array[i], true);   
    }
  } 
  return array1 ;
  }// 使用map
  • DOM 事件相关
    什么是事件委托?4分
    怎么阻止默认动作?3分
    怎么阻止事件冒泡?3分
    事件委托:利用事件冒泡,将子元素的事件处理程序绑定到其祖先元素上。
    假设e为发生的事件,e.preventDeafult() //阻止默认动作
    e.stopPropagation() //阻止事件冒泡

  • 你如何理解 JS 的继承?
    答出基于原型的继承给 5 分
    答出基于 class 的继承给 5 分
    基于原型的继承:JS的实例对象都有都有一个私有属性( proto )指向它的构造函数的原型对象(prototype ),这个原型对象里存放共有属性。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
    几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。

function Student(name) {
    this.name = name;
}

Student.prototype.hello = function () {
    alert('Hello, ' + this.name + '!');
}

基于类的继承:是一个语法糖。将实例对象的共有属性放在类上,用class构造的实例对象后会自动拥有这些共有属性。

class Student {
    constructor(name) {
        this.name = name;
    }
    hello() {
        alert('Hello, ' + this.name + '!');
    }
}
  • 数组排序
    给出正整数数组 array = [2,1,5,3,8,4,9,5]
    请写出一个函数 sort,使得 sort(array) 得到从小到大排好序的数组 [1,2,3,4,5,5,8,9]
    新的数组可以是在 array 自身上改的,也可以是完全新开辟的内存。
let sort=function(arr){
  for(let j=0;j<arr.length-1;j++){
  for(let i=0;i<arr.length-1-j;i++){
    if(arr[i]>arr[i+1]){
      let c;
      c=arr[i];
      arr[i]=arr[i+1];
      arr[i+1]=c;
    }
  }
  }
   return arr;
}

.

  • 你对 Promise 的了解?
    答题要点:
    Promise 的用途
    如何创建一个 new Promise(课堂里让大家背过)
    如何使用 Promise.prototype.then(可查 MDN)
    如何使用 Promise.all(可查 MDN)
    如何使用 Promise.race(可查 MDN)
    创建:return new Promise((resolve,reject)=>{...})
    任务成功调用resolve(result),任务失败调用reject(error),resolve和rehect会再去调用成功和失败函数
// 代码举例
function myAsyncFunction(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onload = () => resolve(xhr.responseText);
    xhr.onerror = () => reject(xhr.statusText);
    xhr.send();
  });
};

使用then: then() 方法返回一个 Promise。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。

var p1 = new Promise((resolve, reject) => {
  resolve('成功!');
  // or
  // reject(new Error("出错了!"));
});

p1.then(value => {
  console.log(value); // 成功!
}, reason => {
  console.error(reason); // 出错了!
});

Promise.all: Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
}); 

Promise.all([p1, p2, p3]).then(values => { 
  console.log(values); // [3, 1337, "foo"] 
});

Promise.race: Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

var p3 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 100, "three");
});
var p4 = new Promise(function(resolve, reject) { 
    setTimeout(reject, 500, "four"); 
});

Promise.race([p3, p4]).then(function(value) {
  console.log(value); // "three"
  // p3 更快,所以它完成了              
}, function(reason) {
  // 未被调用
});
  • 说说跨域。

要点:
什么是同源
什么是跨域
JSONP 跨域
CORS 跨域
同源:源=协议+域名+端口号(可通过window.location或location.origin获得)。如果两个url的协议、域名、端口号完全一致就叫做同源。
跨域:获取不同源的数据
JSONP 跨域:通过自己的script访问一个js文件,这个js文件夹带了非同源的数据,通过callback回调自己的函数,使用了这些数据。
优:(1)可以跨域;(2)兼容IE;缺点:不能发POST请求;script 标签会将资源作为 JS 代码执行,所以可能会被注入恶意代码

CORS 跨域:是一种机制,该机制使用附加的 HTTP 头来告诉浏览器,准许运行在一个源上的Web应用访问位于另一不同源选定的资源。即在被访问的数据的服务器的响应头中设置允许访问的网站的地址。
优:(1)可以跨域(2)使用简单方便、更为安全;(3)支持 POST 请求方式,缺:不兼容IE

response.setHeader('Access-Control-Allow-Origin': 'http://foo.example')
  • 说说你对前端的理解
    评分标准:
    0 分:言之无物,看不下去
    5 分:人云亦云,流于平庸
    10 分满分:见解深刻,有自己的想法
    15 分:惊为天人


    对于前端的本质的理解:
    最开始的认识以为前端就是页面展示,需要画画页面、调整样式。经过一年的学习,知道了工作内容不止如此,内容、样式、交互的操作、动画,包括页面加载,性能等方面都是职责所在。
    而结合计算机历史来看,计算机的诞生之初是做一些人类大脑较难在短时间内处理的操作和完整存储的数据。其实现在的电脑、手机的本质功能也是这样。人和计算机的交互过程就是前端如何让交互界面更加优美、过程更加流程是我理解的前端工程师的职能所在


    对于前端工作流程的理解:
    日常工作会接触一些开发,有意识得了解开发流程。接收产品的需求(对需求有疑问及时讨论),根据需求写代码(可能需要就展示数据对接后端),上线前自测并交付测试同事进行测试,对测试提的bug进行确认和修改。
    当然,发挥的功效可能因人因团队而异,这个需要结合实际工作来看。


    对于前端需要的技能的理解:
    并不是简单的html、CSS和js就可以,提高代码的性能需要学习内存、HTTP,提高效率需要学习框架和库等。另外,想成为大佬可能不是简单的知道怎么用就可以,还要知道为什么可以这么用。
    前端的技能更新迭代的速度较快,需保持一颗学习的心。
    当然,学习不仅在前端技术上,还有其他方面。我在学习前端的路程中感受到了学习的快乐,却也意识到学习带来的快乐绝不应该仅局限于工作。人生的边界很远,做一个有独立思想的人。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值