2024年前端各大公司都考了那些手写题(附带代码),字节跳动前端岗面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

let map = new Map();

let uniqueArr = new Array();  // 数组用于返回结果

for (let i = 0; i < arr.length; i++) {

if(map.has(arr[i])) {  // 如果有该key值

map.set(arr[i], true);

} else {

map.set(arr[i], false);   // 如果没有该key值

uniqueArr.push(arr[i]);

}

}

return uniqueArr ;

}

map 对象保存键值对,与对象类似。但 map 的键可以是任意类型,对象的键只能是字符串类型。

如果数组中只有数字也可以使用普通对象作为哈希表。

filter 配合 indexOf

function unique(arr) {

return arr.filter(function (item, index, arr) {

//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素

//不是那么就证明是重复项,就舍弃

return arr.indexOf(item) === index;

})

}

这里有可能存在疑问,我来举个例子:

const arr = [1,1,2,1,3]

arr.indexOf(arr[0]) === 0 // 1 的第一次出现

arr.indexOf(arr[1]) !== 1 // 说明前面曾经出现过1

reduce 配合 includes

function unique(arr){

let uniqueArr = arr.reduce((acc,cur)=>{

if(!acc.includes(cur)){

acc.push(cur);

}

return acc;

},[]) // []作为回调函数的第一个参数的初始值

return uniqueArr

}

数组扁平化

考察频率: (⭐⭐⭐)

参考代码[3]

forEach

考察频率: (⭐⭐⭐)

Array.prototype.myForEach = function (callbackFn) {

// 判断this是否合法

if (this === null || this === undefined) {

throw new TypeError(“Cannot read property ‘myForEach’ of null”);

}

// 判断callbackFn是否合法

if (Object.prototype.toString.call(callbackFn) !== “[object Function]”) {

throw new TypeError(callbackFn + ’ is not a function’)

}

// 取到执行方法的数组对象和传入的this对象

var _arr = this, thisArg = arguments[1] || window;

for (var i = 0; i < _arr.length; i++) {

// 执行回调函数

callbackFn.call(thisArg, _arr[i], i, _arr);

}

}

reduce

考察频率: (⭐⭐⭐)

Array.prototype.myReduce = function(callbackFn) {

var _arr = this, accumulator = arguments[1];

var i = 0;

// 判断是否传入初始值

if (accumulator === undefined) {

// 没有初始值的空数组调用reduce会报错

if (_arr.length === 0) {

throw new Error(‘initVal and Array.length>0 need one’)

}

// 初始值赋值为数组第一个元素

accumulator = _arr[i];

i++;

}

for (; i<_arr.length; i++) {

// 计算结果赋值给初始值

accumulator = callbackFn(accumulator,  _arr[i], i, _arr)

}

return accumulator;

}

map

Array.prototype.myMap = function(callbackFn) {

var _arr = this, thisArg = arguments[1] || window, res = [];

for (var i = 0; i<_arr.length; i++) {

// 存储运算结果

res.push(callbackFn.call(thisArg, _arr[i], i, _arr));

}

return res;

}

filter

Array.prototype.myFilter = function(callbackFn) {

var _arr = this, thisArg = arguments[1] || window, res = [];

for (var i = 0; i<_arr.length; i++) {

// 回调函数执行为true

if (callbackFn.call(thisArg, _arr[i], i, _arr)) {

res.push(_arr[i]);

}

}

return res;

}

every

Array.prototype.myEvery = function(callbackFn) {

var _arr = this, thisArg = arguments[1] || window;

// 开始标识值为true

// 遇到回调返回false,直接返回false

// 如果循环执行完毕,意味着所有回调返回值为true,最终结果为true

var flag = true;

for (var i = 0; i<_arr.length; i++) {

// 回调函数执行为false,函数中断

if (!callbackFn.call(thisArg, _arr[i], i, _arr)) {

return false;

}

}

return flag;

}

some

Array.prototype.mySome = function(callbackFn) {

var _arr = this, thisArg = arguments[1] || window;

// 开始标识值为false

// 遇到回调返回true,直接返回true

// 如果循环执行完毕,意味着所有回调返回值为false,最终结果为false

var flag = false;

for (var i = 0; i<_arr.length; i++) {

// 回调函数执行为false,函数中断

if (callbackFn.call(thisArg, _arr[i], i, _arr)) {

return true;

}

}

return flag;

}

find/findIndex

Array.prototype.myFind = function(callbackFn) {

var _arr = this, thisArg = arguments[1] || window;

// 遇到回调返回true,直接返回该数组元素

// 如果循环执行完毕,意味着所有回调返回值为false,最终结果为undefined

for (var i = 0; i<_arr.length; i++) {

// 回调函数执行为false,函数中断

if (callbackFn.call(thisArg, _arr[i], i, _arr)) {

return _arr[i];

}

}

return undefined;

}

indexOf

function indexOf(findVal, beginIndex = 0) {

if (this.length < 1 || beginIndex > findVal.length) {

return -1;

}

if (!findVal) {

return 0;

}

beginIndex = beginIndex <= 0 ? 0 : beginIndex;

for (let i = beginIndex; i < this.length; i++) {

if (this[i] == findVal) return i;

}

return -1;

}

实现sort

参考代码[4]

🌊 防抖节流前端开发博客


实现防抖函数debounce

考察频率: (⭐⭐⭐⭐⭐)

function debounce(func, wait, immediate) {

var timeout, result;

var debounced = function () {

var context = this;

var args = arguments;

if (timeout) clearTimeout(timeout);

if (immediate) {

// 如果已经执行过,不再执行

var callNow = !timeout;

timeout = setTimeout(function(){

timeout = null;

}, wait)

if (callNow) result = func.apply(context, args)

}

else {

timeout = setTimeout(function(){

result = func.apply(context, args)

}, wait);

}

return result;

};

debounced.cancel = function() {

clearTimeout(timeout);

timeout = null;

};

return debounced;

}

实现节流函数throttle

考察频率: (⭐⭐⭐⭐⭐)

// 第四版

function throttle(func, wait, options) {

var timeout, context, args, result;

var previous = 0;

if (!options) options = {};

var later = function() {

previous = options.leading === false ? 0 : new Date().getTime();

timeout = null;

func.apply(context, args);

if (!timeout) context = args = null;

};

var throttled = function() {

var now = new Date().getTime();

if (!previous && options.leading === false) previous = now;

var remaining = wait - (now - previous);

context = this;

args = arguments;

if (remaining <= 0 || remaining > wait) {

if (timeout) {

clearTimeout(timeout);

timeout = null;

}

previous = now;

func.apply(context, args);

if (!timeout) context = args = null;

} else if (!timeout && options.trailing !== false) {

timeout = setTimeout(later, remaining);

}

};

return throttled;

}

⛲ Object篇


能不能写一个完整的深拷贝

考察频率: (⭐⭐⭐⭐⭐)

const getType = obj => Object.prototype.toString.call(obj);

const isObject = (target) => (typeof target === ‘object’ || typeof target === ‘function’) && target !== null;

const canTraverse = {

‘[object Map]’: true,

‘[object Set]’: true,

‘[object Array]’: true,

‘[object Object]’: true,

‘[object Arguments]’: true,

};

const mapTag = ‘[object Map]’;

const setTag = ‘[object Set]’;

const boolTag = ‘[object Boolean]’;

const numberTag = ‘[object Number]’;

const stringTag = ‘[object String]’;

const symbolTag = ‘[object Symbol]’;

const dateTag = ‘[object Date]’;

const errorTag = ‘[object Error]’;

const regexpTag = ‘[object RegExp]’;

const funcTag = ‘[object Function]’;

const handleRegExp = (target) => {

const { source, flags } = target;

return new target.constructor(source, flags);

}

const handleFunc = (func) => {

// 箭头函数直接返回自身

if(!func.prototype) return func;

const bodyReg = /(?<={)(.|\n)+(?=})/m;

const paramReg = /(?<=().+(?=)\s+{)/;

const funcString = func.toString();

// 分别匹配 函数参数 和 函数体

const param = paramReg.exec(funcString);

const body = bodyReg.exec(funcString);

if(!body) return null;

if (param) {

const paramArr = param[0].split(‘,’);

return new Function(…paramArr, body[0]);

} else {

return new Function(body[0]);

}

}

const handleNotTraverse = (target, tag) => {

const Ctor = target.constructor;

switch(tag) {

case boolTag:

return new Object(Boolean.prototype.valueOf.call(target));

case numberTag:

return new Object(Number.prototype.valueOf.call(target));

case stringTag:

return new Object(String.prototype.valueOf.call(target));

case symbolTag:

return new Object(Symbol.prototype.valueOf.call(target));

case errorTag:

case dateTag:

return new Ctor(target);

case regexpTag:

return handleRegExp(target);

case funcTag:

return handleFunc(target);

default:

return new Ctor(target);

}

}

const deepClone = (target, map = new WeakMap()) => {

if(!isObject(target))

return target;

let type = getType(target);

let cloneTarget;

if(!canTraverse[type]) {

// 处理不能遍历的对象

return handleNotTraverse(target, type);

}else {

// 这波操作相当关键,可以保证对象的原型不丢失!

let ctor = target.constructor;

cloneTarget = new ctor();

}

if(map.get(target))

return target;

map.set(target, true);

if(type === mapTag) {

//处理Map

target.forEach((item, key) => {

cloneTarget.set(deepClone(key, map), deepClone(item, map));

})

}

if(type === setTag) {

//处理Set

target.forEach(item => {

cloneTarget.add(deepClone(item, map));

})

}

// 处理数组和对象

for (let prop in target) {

if (target.hasOwnProperty(prop)) {

cloneTarget[prop] = deepClone(target[prop], map);

}

}

return cloneTarget;

}

参考博客[5]

实现new

考察频率: (⭐⭐⭐⭐)

function createObject(Con) {

// 创建新对象obj

// var obj = {};也可以

var obj = Object.create(null);

// 将obj.proto -> 构造函数原型

// (不推荐)obj.proto = Con.prototype

Object.setPrototypeOf(obj, Con.prototype);

// 执行构造函数,并接受构造函数返回值

const ret = Con.apply(obj, [].slice.call(arguments, 1));

// 若构造函数返回值为对象,直接返回该对象

// 否则返回obj

return typeof(ret) === ‘object’ ? ret: obj;

}

继承

考察频率: (⭐⭐⭐⭐)

原型链继承
借用构造函数(经典继承)
组合继承
原型式继承
寄生式继承
寄生组合式继承
Class实现继承(补充一下)

class Animal {

constructor(name) {

this.name = name

}

getName() {

return this.name

}

}

class Dog extends Animal {

constructor(name, age) {

super(name)

this.age = age

}

}

参考代码[6]

实现object.create

function newCreate(proto, propertiesObject) {

if (typeof proto !== ‘object’ && typeof proto !== ‘function’) {

throw TypeError('Object prototype may only be an Object: ’ + proto)

}

function F() { }

F.prototype = proto

const o = new F()

if (propertiesObject !== undefined) {

Object.keys(propertiesObject).forEach(prop => {

let desc = propertiesObject[prop]

if (typeof desc !== ‘object’ || desc === null) {

throw TypeError('Object prorotype may only be an Object: ’ + desc)

} else {

Object.defineProperty(o, prop, desc)

}

})

}

return o

}

🚂 Function篇


call

考察频率: (⭐⭐⭐⭐)

Function.prototype.myCall = function (thisArg) {

thisArg = thisArg || window;

thisArg.func = this;

const args = []

for (let i = 1; i<arguments.length; i++) {

args.push(‘arguments[’+ i + ‘]’)

}

const result = eval(‘thisArg.func(’ + args +‘)’)

delete thisArg.func;

return result;

}

bind

考察频率: (⭐⭐⭐⭐)

Function.prototype.sx_bind = function (obj, …args) {

obj = obj || window

const fn = Symbol()

obj[fn] = this

const _this = this

const res = function (…innerArgs) {

console.log(this, _this)

if (this instanceof _this) {

this[fn] = _this

thisfn

delete this[fn]

} else {

objfn

delete obj[fn]

}

}

res.prototype = Object.create(this.prototype)

return res

}

apply

考察频率: (⭐⭐⭐⭐)

Function.prototype.myApply = function (thisArg, arr) {

thisArg = thisArg || window;

thisArg.func = this;

const args = []

for (let i = 0; i<arr.length; i++) {

args.push(‘arr[’+ i + ‘]’)

}

const result = eval(‘thisArg.func(’ + args +‘)’)

delete thisArg.func;

return result;

}

实现柯里化

考察频率: (⭐⭐⭐)

参考代码[7]

实现链式调用

参考代码[8]

偏函数

参考代码[9]

🌍 ajax 与 jsonp


考察频率: (⭐⭐⭐)

实现ajax

function ajax({

url= null,

method = ‘GET’,

dataType = ‘JSON’,

async = true}){

return new Promise((resolve, reject) => {

let xhr = new XMLHttpRequest()

xhr.open(method, url, async)

xhr.responseType = dataType

xhr.onreadystatechange = () => {

if(!/1\d{2}$/.test(xhr.status)) return;

if(xhr.readyState === 4) {

let result = xhr.responseText

resolve(result)

}

}

xhr.onerror = (err) => {

reject(err)

}

xhr.send()

})

}

实现jsonp

const jsonp = ({ url, params, callbackName }) => {

const generateUrl = () => {

let dataSrc = ‘’

for (let key in params) {

if (params.hasOwnProperty(key)) {

dataSrc += ${key}=${params[key]}&

}

}

dataSrc += callback=${callbackName}

return ${url}?${dataSrc}

}

return new Promise((resolve, reject) => {

const scriptEle = document.createElement(‘script’)

scriptEle.src = generateUrl()

document.body.appendChild(scriptEle)

window[callbackName] = data => {

resolve(data)

document.removeChild(scriptEle)

}

})

}

🛫 ES6篇


实现set

class Set {

constructor() {

this.items = {};

this.size = 0;

}

has(element) {

return element in this.items;

}

add(element) {

if(! this.has(element)) {

this.items[element] = element;

this.size++;

}

return this;

}

delete(element) {

if (this.has(element)) {

delete this.items[element];

this.size–;

}

return this;

}

clear() {

this.items = {}

this.size = 0;

}

values() {

let values = [];

for(let key in this.items) {

if(this.items.hasOwnProperty(key)) {

values.push(key);

}

}

return values;

}

}

实现 map

function defaultToString(key) {

if(key === null) {

return ‘NULL’;

} else if (key === undefined) {

return ‘UNDEFINED’

} else if (Object.prototype.toString.call(key) === ‘[object Object]’ || Object.prototype.toString.call(key) === ‘[object Array]’) {

return JSON.stringify(key);

}

return key.toString();

}

class Map {

constructor() {

this.items = {};

this.size = 0;

}

set(key, value) {

if(!this.has(key)) {

this.items[defaultToString(key)] = value;

this.size++;

}

文末

我一直觉得技术面试不是考试,考前背背题,发给你一张考卷,答完交卷等通知。

首先,技术面试是一个 认识自己 的过程,知道自己和外面世界的差距。

更重要的是,技术面试是一个双向了解的过程,要让对方发现你的闪光点,同时也要 试图去找到对方的闪光点,因为他以后可能就是你的同事或者领导,所以,面试官问你有什么问题的时候,不要说没有了,要去试图了解他的工作内容、了解这个团队的氛围。

前端面试题汇总

JavaScript

性能

linux

前端资料汇总

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
faultToString(key) {

if(key === null) {

return ‘NULL’;

} else if (key === undefined) {

return ‘UNDEFINED’

} else if (Object.prototype.toString.call(key) === ‘[object Object]’ || Object.prototype.toString.call(key) === ‘[object Array]’) {

return JSON.stringify(key);

}

return key.toString();

}

class Map {

constructor() {

this.items = {};

this.size = 0;

}

set(key, value) {

if(!this.has(key)) {

this.items[defaultToString(key)] = value;

this.size++;

}

文末

我一直觉得技术面试不是考试,考前背背题,发给你一张考卷,答完交卷等通知。

首先,技术面试是一个 认识自己 的过程,知道自己和外面世界的差距。

更重要的是,技术面试是一个双向了解的过程,要让对方发现你的闪光点,同时也要 试图去找到对方的闪光点,因为他以后可能就是你的同事或者领导,所以,面试官问你有什么问题的时候,不要说没有了,要去试图了解他的工作内容、了解这个团队的氛围。

前端面试题汇总

JavaScript

性能

linux

前端资料汇总

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-RjxFhwW8-1713117785368)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!


  1. 23 ↩︎

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值