2024前端面试真题【手写篇】

求几个数的总和(2,3,4,5,6,6,7,7,8,8,8)

arr.reduce((total, currentVal, currentInd, arr)=>{}, initialVal)

const arr = [23456677888]
const sum = arr.reduce((total, val) => total + val, 0)

离开页面弹出确认框

window.onbeforeunload = _=>alert('确认离开页面吗?')

将URL中的查询字符串参数转换为对象数据

  • URLSearchParams:将查询参数字符串解析为一个可迭代数据
  • Object.fromEntries:将可迭代数据转换为对象
const query = 'name=John&age=30';

// 将字符串解析为对象
const parseQuery = query => Object.fromEntries(new URLSearchParams(query));

// 结果: parseQuery = { name: 'John', age: '30' }

将秒数转换为时间格式的字符串

const seconds = 4532

const toTimeStr = sec => new Date(sec * 1000).toISOString().substr(11, 8);

toTimeStr(seconds) // 输出"01:15:32"

创建包含值为指定数字范围的数组

Array.from()用于将类数组对象或可迭代对象转换为一个新的数据。基本语法:Array.from(arrayLike, [, mapFn [, thisArg])

const arr = Array.from({length: 5}, num => num *3)

Promise

Promise的三个状态:

  • pending:操作待定
  • rejected:操作失败
  • fulfilled:操作成功

隐式转换

  • [] == ![]:true

实现New

步骤

  1. 创建一个新的空对象
  2. 设置原型,将对象的原型设置为函数的prototype对象
  3. 修改函数的this指向为这个对象,执行构造函数的代码
  4. 判断函数返回值类型(值类型则返回创建的对象;引用类型则返回这个引用类型的对象)
function objNew(constructor, ...args) {
	// 必须是一个函数
	if(typeof constructor !== 'function') {
		throw "objNew function the first param must be a  function"
	}
	// 基于原型链 创建一个新对象 继承构造函数constructor的原型对象上的属性
	let objNew = Object.create(constructor.prototype)
	// 将objNew作为this 执行constructor 传入传入
	let res = constructor.apply(newObj, args)
	let isObject = typeof res === 'object' && res !== null
	// 判断函数的执行结果是否是函数
	let isFunction = typeof res === 'function'
	return isObject || isFunction ? res : objNew
}

// 使用
function Person (name, age) {
	this.name = name;
	this.age = age;
}

Person.prototype.say = function() {
	console.log(`say hello to ${this.name}(of ${this.age})`)
}

let xiaoM = objNew(Person, 'xiaoMing', 18)
console.log(xiaoM.name) // xiaoMing
console.log(xiaoM) // Person(name:'xiaoMing',age:18)
xiaoM.say() // 18

用递归算法实现,数组长度为5且元素的随机数在2-32间不重复的值

function randomArr(arr) {
	var num = randomNumber();
    if (arr.indexOf(num)< 0){
        arr[i] = num;
        i++;
    } else {
        num = randomNumber();
    }
    if (i>=arr.length){
        return;
    }else{
        randomArr(arr,num)
    }
}
function randomNumber() {
    return Math.floor(Math.random()*31 + 2)
}

var arr = new Array(5);
var i = 0;
randomArr(arr);

圣杯布局和双飞翼布局的理解和区别,代码实现

两者都是为了不让左右遮住middle

  • 圣杯布局:父元素设置padding给左右腾位置,从而不会遮住middle内容
<body>
<div id="hd">header</div>
<div id="bd">
  <div id="middle">middle</div>
  <div id="left">left</div>
  <div id="right">right</div>
</div>
<div id="footer">footer</div>
</body>
<style>
#hd{
    height:50px;
    background: #666;
    text-align: center;
}
#bd{
    /*左右栏通过添加负的margin放到正确的位置了,此段代码是为了摆正中间栏的位置*/
    padding:0 200px 0 180px;
    height:100px;
}
#middle{
    float:left;
    width:100%;/*左栏上去到第一行*/
    height:100px;
    background:blue;
}
#left{
    float:left;
    width:180px;
    height:100px;
    margin-left:-100%;
    background:#0c9;
    /*中间栏的位置摆正之后,左栏的位置也相应右移,通过相对定位的left恢复到正确位置*/
    position:relative;
    left:-180px;
}
#right{
    float:left;
    width:200px;
    height:100px;
    margin-left:-200px;
    background:#0c9;
    /*中间栏的位置摆正之后,右栏的位置也相应左移,通过相对定位的right恢复到正确位置*/
    position:relative;
    right:-200px;
}
#footer{
    height:50px;
    background: #666;
    text-align: center;
}
</style>
  • 双飞翼布局:middle设置margin,限制内部内容区域,以防左右遮挡middle内容
<body>
<div id="hd">header</div> 
  <div id="middle">
    <div id="inside">middle</div>
  </div>
  <div id="left">left</div>
  <div id="right">right</div>
  <div id="footer">footer</div>
</body>
<style>
#hd{
    height:50px;
    background: #666;
    text-align: center;
}
#middle{
    float:left;
    width:100%;/*左栏上去到第一行*/     
    height:100px;
    background:blue;
}
#left{
    float:left;
    width:180px;
    height:100px;
    margin-left:-100%;
    background:#0c9;
}
#right{
    float:left;
    width:200px;
    height:100px;
    margin-left:-200px;
    background:#0c9;
}

/*给内部div添加margin,把内容放到中间栏,其实整个背景还是100%*/ 
#inside{
    margin:0 200px 0 180px;
    height:100px;
}
#footer{  
   clear:both; /*记得清楚浮动*/  
   height:50px;     
   background: #666;    
   text-align: center; 
} 
</style>

写一个方法去掉首尾空格

const str = '  s t  r  '

const POSITION = Object.freeze({
  left: Symbol(),
  right: Symbol(),
  both: Symbol(),
  center: Symbol(),
  all: Symbol(),
})

function trim(str, position = POSITION.both) {
  if (!!POSITION[position]) throw new Error('unexpected position value')
  
  switch(position) {
      case(POSITION.left):
        str = str.replace(/^\s+/, '')
        break;
      case(POSITION.right):
        str = str.replace(/\s+$/, '')
        break;
      case(POSITION.both):
        str = str.replace(/^\s+/, '').replace(/\s+$/, '')
        break;
      case(POSITION.center):
        while (str.match(/\w\s+\w/)) {
          str = str.replace(/(\w)(\s+)(\w)/, `$1$3`)
        }
        break;
      case(POSITION.all):
        str = str.replace(/\s/g, '')
        break;
      default: 
  }
  
  return str
}

const result = trim(str)

console.log(`|${result}|`) //  |s t  r| 

删除字符串最后一个指定字符

//方法一  lastIndexOf()
function delLast (str,del) {
	if (tpeof str !== 'string') {
	alert('请确认要删除的对象为字符串!');
	retrun false;
	} else {
	let index = str.lastIndexOf(del);
	str.substring(0,index ) + str.substring(index+1,str.length);
	}
}

//方法二  反转字符串
function delLast(str, target) {
  return str.split('').reverse().join('').replace(target, '').split('').reverse().join('');
}

const str = delLast('asdfghhj', 'h')

console.log(str) // asdfghj 

写一个方法把下划线命名转为驼峰命名

//方法一  
function toCamel(str) {
	 if(str.split('_').length==1)return;
	  str = str.replace(/(\w)/, (match, $1) => `${$1.toUpperCase()}`)
	  while(str.match(/\w_\w/)) {
	    str = str.replace(/(\w)(_)(\w)/, (match, $1, $2, $3) => `${$1}${$3.toUpperCase()}`)
	  }
	  return str
}

console.log(toCamel('a_c_def')) // ACDef 

//方法二
function changeStr(str){
   if(str.split('_').length==1)return;
   str.split('_').reduce((a,b)=>{
     return a+b.substr(0,1).toUpperCase() + b.substr(1)
   })
}

写一个把字符串大小写切换的方法

function caseConvert(str){
    return str.replace(/([a-z]*)([A-Z]*)/g, (m, s1, s2)=>{
	return `${s1.toUpperCase()}${s2.toLowerCase()}`
    })
}
caseConvert('AsA33322A2aa') //aSa33322a2AA

css实现三角形

.rect {
      width: 0;
      height: 0;
      background-color: #fff;
      border-right: 100px solid transparent;
      border-left: 100px solid transparent;
      border-top: 100px solid rgb(29, 156, 194);
      border-bottom: 100px solid transparent;
 }
	/*方法二*/
	.triangle:after{
	    content: '';
	    border: 35px solid transparent;
	    border-bottom-color: lightgreen;
	}
  1. 写一个去除制表符和换行符的方法
    \s会匹配空格,还是老实用[\t\n\v\r\f]
var str = '大家好  阿斯蒂芬阿斯顿\n发生的发生';
function fn(str) {
     var s = str.replace(/\t|\n|\r|\f/g, "");
     return s;
 }
 console.log(fn(str))

统计某个字符或者字符串在另一个字符串中出现的次数

//方法一
function count(str, param) {
  const reg = new RegExp(param, 'g');
  return str.match(reg).length;
}
//方法二
var childInNums = parent.split(child).length - 1

简单的加密字符串的方法

// String.fromCharCode()  返回字符串的Unicode编码
function strEncrypt(str) {
  return str.split('').map(s => {
    return String.fromCharCode(s.charCodeAt() + 1)
  }).join('')
}

console.log(strEncrypt('hello world')) // ifmmp!xpsme

简单的判断数据类型的方法

// "Array", "Function", "Object", "RegExp", "Date"
// "Boolean", "Number", "String"
function myType(v){
    return Object.prototype.toString.call(v).replace(/^.{8}(.+)]$/,(m,$1)=> $1.toLowerCase());
}

获取当前url查询字符串中参数的方法

// window.location.search可直接获取
function urlParam(url){
    const param = {};
    url.replace(/[?&](.*?)=([^&]*)/g,(m,$1,$2)=> param[$1] = $2);
    return param;
}

数组去重的方法(支持多维)

function flat(arr, target) {
  arr.forEach(item => {
    if (Array.isArray(item)) {
      flat(item, target)
    } else {
      target.push(item)
    }
  })
}

function flatArr(arr) {
  let result = []
  flat(arr, result)
  return result
}

function uniqueArr(arr) {
  return [...new Set(flatArr(arr))]
}

const result = uniqueArr([1, 2, 3, 4, [3, 4, [4, 6]]])

console.log(result) // 1,2,3,4,6

检测中文的方法:

//使用的Unicode 编码 4e00 和 9fa5 分别表示第一个汉字和最后一个汉字的编码
function isChinese(str) {
  const re = /^[\u4e00-\u9fa5]+$/;
  return re.test(str);
}

获取数组最大最小值的方法

const getMinAndMax = arr => ({
  // 数组展开在 ES5 中可以用 apply 代替
  // ES5: Math.min.apply(null, arr)
  min: Math.min(...arr),
  max: Math.max(...arr)
});

写一个方法判断是否是回文字符串

var isPalindrome = function(s) {
	  if (s.length === 1) return true
	  const str = s.replace(/[^a-zA-Z0-9]/g, "").toLowerCase()
	  const strReverse = str.split('').reverse().join('')
	  return str === strReverse
};

div模拟texterea

<style>
.edit{
    width: 300px;
    height: 200px;
    padding: 5px;
    border: solid 1px #ccc;
    resize: both;
    overflow:auto;
}
</style>
<body>
    <h3>用一个div模拟textarea的实现</h3>
      <div class="edit" contenteditable="true">
        这里是可以编辑的内容,配合容器的 overflow ,多行截断,自定义滚动条,简直好用的不要不要的。
    </div>
</body>

找出一个字符串中最长的字符

function maxLengthString(str){
 str.split('').reduce(function(start,end){
   return start>end?start.length:end.length
 })
}

实现单行文本居中和多行文本左对齐,超出显示…

.one {
  text-align: center
}
/*text-overflow: ellipsis  有兼容问题*/
.multi {
  overflow: hidden
  text-overflow: ellipsis
  display: -webkit-box
  -webkit-line-clamp: 3
  -webkit-box-orient: vertical
}

让英文单词首字母大写

/*text-transform:capitalize(强制首字母大写) 、uppercase(全大写)、lowercase、none(阻止大小写转换)、full-width(实验性属性值)*/
.demo {
  text-transform: capitalize;
}

用js写一个事件监听方法

class EventBus {
   constructor() {
        this.events = {}
    }

  on(eventName, callback) {
    const events = this.events;
    if (!events[eventName]) {
      events[eventName] = [];
    }
    events[eventName].push(callback);
    return this;
  }

  emit(eventName, params) {
    const events = this.events;
    if (events[eventName]) {
      events[eventName].forEach(cb => cb(params));
    }
    return this;
  }
}

使用正则表达式去掉html中标签与标签之间的空格

const html = `
<div>
   <span>      我两边怎么有空格?  </span>
</div>
`
console.log(html.replace(/>\s*(\S*)\s*</g, ">$1<"));

写一个方法给多维数组降维

let arr = [1, 2, {}, 3, [4, {}, 5], [6, 7, [8, null, 9]]];
//递归
function flat (arr) {
  let ret = []
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] instanceof (Array)) {
      ret = ret.concat(flat(arr[i]))
    }
    else {
      ret.push(arr[i])
    }
  }
  return ret
}
console.log(flat(arr))
//ES10新增的内置方法
arr.flat(Infinity)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值