当前位置:   article > 正文

史上最全,熬夜整理56个JavaScript高级的手写知识点,专业扫盲_javascript手写笔记总结

javascript手写笔记总结

17、计算一个对象的层数

题目描述:给你一个对象,统计一下它的层数

const obj = {

a: { b: [1] },

c: { d: { e: { f: 1 } } }

}

console.log(loopGetLevel(obj)) // 4

实现如下:

function loopGetLevel(obj) {

var res = 1;

function computedLevel(obj, level) {

var level = level ? level : 0;

if (typeof obj === ‘object’) {

for (var key in obj) {

if (typeof obj[key] === ‘object’) {

computedLevel(obj[key], level + 1);

} else {

res = level + 1 > res ? level + 1 : res;

}

}

} else {

res = level > res ? level : res;

}

}

computedLevel(obj)

return res

}

18、对象的扁平化

题目描述:

const obj = {

a: {

b: 1,

c: 2,

d: {e: 5}

},

b: [1, 3, {a: 2, b: 3}],

c: 3

}

flatten(obj) 结果返回如下

// {

// ‘a.b’: 1,

// ‘a.c’: 2,

// ‘a.d.e’: 5,

// ‘b[0]’: 1,

// ‘b[1]’: 3,

// ‘b[2].a’: 2,

// ‘b[2].b’: 3

// c: 3

// }

实现如下:

const isObject = (val) => typeof val === “object” && val !== null

function flatten(obj) {

if (!isObject(obj)) return

const res = {}

const dfs = (cur, prefix) => {

if (isObject(cur)) {

if (Array.isArray(cur)) {

cur.forEach((item, index) => {

dfs(item, ${prefix}[${index}])

})

} else {

for(let key in cur) {

dfs(cur[key], ${prefix}${prefix ? '.' : ''}${key})

}

}

} else {

res[prefix] = cur

}

}

dfs(obj, ‘’)

return res

}

// 测试

console.log(flatten(obj))

19、实现(a == 1 && a == 2 && a == 3)为true

题目描述:实现(a == 1 && a == 2 && a == 3)为true

// 第一种方法

var a = {

i: 1,

toString: function () {

return a.i++;

}

}

console.log(a == 1 && a == 2 && a == 3) // true

// 第二种方法

var a = [1, 2, 3];

a.join = a.shift;

console.log(a == 1 && a == 2 && a == 3); // true

// 第三种方法

var val = 0;

Object.defineProperty(window, ‘a’, {

get: function () {

return ++val;

}

});

console.log(a == 1 && a == 2 && a == 3) // true

20、实现限制并发的Promise调度器

题目描述:JS 实现一个带并发限制的异步调度器 Scheduler,保证同时运行的任务最多有两个

addTask(1000,“1”);

addTask(500,“2”);

addTask(300,“3”);

addTask(400,“4”);

的输出顺序是:2 3 1 4

整个的完整执行流程:

一开始1、2两个任务开始执行

500ms时,2任务执行完毕,输出2,任务3开始执行

800ms时,3任务执行完毕,输出3,任务4开始执行

1000ms时,1任务执行完毕,输出1,此时只剩下4任务在执行

1200ms时,4任务执行完毕,输出4

实现如下:

class Scheduler {

constructor(limit) {

this.queue = []

this.limit = limit

this.count = 0

}

add(time, order) {

const promiseCreator = () => {

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

setTimeout(() => {

console.log(order)

resolve()

}, time)

})

}

this.queue.push(promiseCreator)

}

taskStart() {

for(let i = 0; i < this.limit; i++) {

this.request()

}

}

request() {

if (!this.queue.length || this.count >= this.limit) return

this.count++

this.queue.shift()().then(() => {

this.count–

this.request()

})

}

}

// 测试

const scheduler = new Scheduler(2);

const addTask = (time, order) => {

scheduler.add(time, order);

};

addTask(1000, “1”);

addTask(500, “2”);

addTask(300, “3”);

addTask(400, “4”);

scheduler.taskStart();

21、实现lazyMan函数

题目描述:

实现一个LazyMan,可以按照以下方式调用:

LazyMan(“Hank”)输出:

Hi! This is Hank!

LazyMan(“Hank”).sleep(10).eat(“dinner”)输出

Hi! This is Hank!

//等待10秒…

Wake up after 10

Eat dinner~

LazyMan(“Hank”).eat(“dinner”).eat(“supper”)输出

Hi This is Hank!

Eat dinner~

Eat supper~

LazyMan(“Hank”).eat(“supper”).sleepFirst(5)输出

//等待5秒

Wake up after 5

Hi This is Hank!

Eat supper

实现如下:

class _LazyMan {

constructor(name) {

this.tasks = []

const task = () => {

console.log(Hi! This is ${name})

this.next()

}

this.tasks.push(task)

setTimeout(() => {

this.next()

}, 0)

}

next() {

const task = this.tasks.shift()

task && task()

}

sleep(time) {

this.sleepWrapper(time, false)

return this

}

sleepFirst(time) {

this.sleepWrapper(time, true)

return this

}

sleepWrapper(time, first) {

const task = () => {

setTimeout(() => {

console.log(Wake up after ${time})

this.next()

}, time * 1000)

}

if (first) {

this.tasks.unshift(task)

} else {

this.tasks.push(task)

}

}

eat(food) {

const task = () => {

console.log(Eat ${food});

this.next();

};

this.tasks.push(task);

return this;

}

}

// 测试

const lazyMan = (name) => new _LazyMan(name)

lazyMan(‘Hank’).sleep(1).eat(‘dinner’)

lazyMan(‘Hank’).eat(‘dinner’).eat(‘supper’)

lazyMan(‘Hank’).eat(‘supper’).sleepFirst(5)

22、实现add函数

题目描述:实现一个 add 方法 使计算结果能够满足如下预期:

  • add(1)(2)(3)()=6
  • add(1,2,3)(4)()=10

function add(…args1) {

let allArgs = […args1]

function fn(…args2) {

if (!args2.length) return fn.toString()

allArgs = […allArgs, …args2]

return fn

}

fn.toString = function () {

return allArgs.reduce((pre, next) => pre + next)

}

return fn

}

// 测试

console.log(add(1)(2)(3)())

console.log(add(1, 2)(3)())

23、实现一个合格的深拷贝

24、实现 Promise

25、实现 async/await

Array篇


定义一个测试数组

const players = [

{ name: ‘科比’, num: 24 },

{ name: ‘詹姆斯’, num: 23 },

{ name: ‘保罗’, num: 3 },

{ name: ‘威少’, num: 0 },

{ name: ‘杜兰特’, num: 35 }

]

26、forEach

参数代表含义

  • item:遍历项

  • index:遍历项的索引

  • arr:数组本身

Array.prototype.sx_forEach = function (callback) {

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

callback(this[i], i, this)

}

}

players.sx_forEach((item, index, arr) => {

console.log(item, index)

})

// { name: ‘科比’, num: 24 } 0

// { name: ‘詹姆斯’, num: 23 } 1

// { name: ‘保罗’, num: 3 } 2

// { name: ‘威少’, num: 0 } 3

// { name: ‘杜兰特’, num: 35 } 4

27、map

参数代表含义

  • item:遍历项

  • index:遍历项的索引

  • arr:数组本身

Array.prototype.sx_map = function (callback) {

const res = []

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

res.push(callback(this[i], i, this))

}

return res

}

console.log(players.sx_map((item, index) => ${item.name}--${item.num}--${index}))

// [ ‘科比–24–0’, ‘詹姆斯–23–1’, ‘保罗–3–2’, ‘威少–0–3’, ‘杜兰特–35–4’ ]

28、filter

参数代表含义

  • item:遍历项

  • index:遍历项的索引

  • arr:数组本身

Array.prototype.sx_filter = function (callback) {

const res = []

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

callback(this[i], i, this) && res.push(this[i])

}

return res

}

console.log(players.sx_filter(item => item.num >= 23))

// [

// { name: ‘科比’, num: 24 },

// { name: ‘詹姆斯’, num: 23 },

// { name: ‘杜兰特’, num: 35 }

// ]

29、every

参数代表含义

  • item:遍历项

  • index:遍历项的索引

  • arr:数组本身

Array.prototype.sx_every = function (callback) {

let flag = true

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

flag = callback(this[i], i, this)

if (!flag) break

}

return flag

}

console.log(players.sx_every(item => item.num >= 23)) // false

console.log(players.sx_every(item => item.num >= 0)) // true

30、some

参数代表含义

  • item:遍历项

  • index:遍历项的索引

  • arr:数组本身

Array.prototype.sx_some = function (callback) {

let flag = false

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

flag = callback(this[i], i, this)

if (flag) break

}

return flag

}

console.log(players.sx_some(item => item.num >= 23)) // true

console.log(players.sx_some(item => item.num >= 50)) // false

31、reduce

参数代表含义

  • pre:前一项

  • next:下一项

  • index:当前索引

  • arr:数组本身

Array.prototype.sx_reduce = function (callback, …args) {

let start = 0, pre

if (args.length) {

pre = args[0]

} else {

pre = this[0]

start = 1

}

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

pre = callback(pre, this[i], i, this)

}

return pre

}

// 计算所有num相加

const sum = players.sx_reduce((pre, next) => {

return pre + next.num

}, 0)

console.log(sum) // 85

32、findIndex

参数代表含义

  • item:遍历项

  • index:遍历项的索引

  • arr:数组本身

Array.prototype.sx_findIndex = function (callback) {

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

if (callback(this[i], i, this)) {

return i

}

}

return -1

}

console.log(players.sx_findIndex(item => item.name === ‘科比’)) // 0

console.log(players.sx_findIndex(item => item.name === ‘安东尼’)) // -1

33、find

参数代表含义

  • item:遍历项

  • index:遍历项的索引

  • arr:数组本身

Array.prototype.sx_find = function (callback) {

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

if (callback(this[i], i, this)) {

return this[i]

}

}

return undefined

}

console.log(players.sx_find(item => item.name === ‘科比’)) // { name: ‘科比’, num: 24 }

console.log(players.sx_find(item => item.name === ‘安东尼’)) // undefined

34、fill

用处:填充数组

参数代表含义

  • initValue:填充的值

  • start:开始填充索引,默认0

  • end:结束填充索引,默认length

Array.prototype.sx_fill = function (value, start = 0, end) {

end = end || this.length

for (let i = start; i < end; i++) {

this[i] = value

}

return this

}

console.log(players.sx_fill(‘林三心’, 1, 3))

// [

// { name: ‘科比’, num: 24 },

// ‘林三心’,

// ‘林三心’,

// ‘林三心’,

// { name: ‘杜兰特’, num: 35 }

// ]

35、includes

用处:查找元素,查到返回true,反之返回false,可查找NaN

Array.prototype.sx_includes = function (value, start = 0) {

if (start < 0) start = this.length + start

const isNaN = Number.isNaN(value)

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

if (this[i] === value || (isNaN && Number.isNaN(this[i])) {

return true

}

}

return false

}

console.log([1, 2, 3].sx_includes(2)) // true

console.log([1, 2, 3, NaN].sx_includes(NaN)) // true

console.log([1, 2, 3].sx_includes(1, 1)) // false

36、join

用处:将数组用分隔符拼成字符串,分隔符默认为,

Array.prototype.sx_join = function (s = ‘,’) {

let str = ‘’

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

str = i === 0 ? ${str}${this[i]} : ${str}${s}${this[i]}

}

return str

}

console.log([1, 2, 3].sx_join()) // 1,2,3

console.log([1, 2, 3].sx_join('')) // 12*3

37、flat

Array.prototype.sx_flat = function (num = Infinity) {

let arr = this

let i = 0

while (arr.some(item => Array.isArray(item))) {

arr = [].concat(…arr)

i++

if (i >= num) break

}

return arr

}

const testArr = [1, [2, 3, [4, 5]], [8, 9]]

console.log(testArr.sx_flat(1))

// [1, 2, 3, 4, 5, 8, 9]

38、splice

难点

  • 截取长度和替换长度的比较,不同情况

Array.prototype.sx_splice = function (start, length, …values) {

if (length === 0) return []

length = start + length > this.length - 1 ? this.length - start : length

console.log(length)

const res = [], tempArr = […this]

for (let i = start; i < start + values.length; i++) {

this[i] = values[i - start]

}

this.length = start + values.length

if (values.length < length) {

const cha = length - values.length

console.log(cha)

for (let i = start + values.length; i < tempArr.length; i++) {

this[i] = tempArr[i + cha]

}

this.length = this.length - cha

}

if (values.length > length) {

for (let i = start + length; i < tempArr.length; i++) {

this.push(tempArr[i])

}

}

for (let i = start; i < start + length; i++) {

res.push(tempArr[i])

}

return res

}

Object篇


定义一个测试对象

const obj = {

name: ‘林三心’,

age: 22,

gender: ‘男’

}

39、entries

用处:将对象转成键值对数组

Object.prototype.sx_entries = function (obj) {

const res = []

for (let key in obj) {

obj.hasOwnProperty(key) && res.push([key, obj[key]])

}

return res

}

console.log(Object.sx_entries(obj))

// [ [ ‘name’, ‘林三心’ ], [ ‘age’, 22 ], [ ‘gender’, ‘男’ ] ]

40、fromEntries

用处:跟entries相反,将键值对数组转成对象

Object.prototype.sx_fromEntries = function (arr) {

const obj = {}

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

const [key, value] = arr[i]

obj[key] = value

}

return obj

}

console.log(Object.sx_fromEntries([[‘name’, ‘林三心’], [‘age’, 22], [‘gender’, ‘男’]]))

// { name: ‘林三心’, age: 22, gender: ‘男’ }

41、keys

用处:将对象的key转成一个数组合集

Object.prototype.sx_keys = function (obj) {

const keys = []

for (let key in obj) {

obj.hasOwnProperty(key) && res.push(key)

}

return keys

}

console.log(Object.keys(obj))

// [ ‘name’, ‘age’, ‘gender’ ]

42、values

用处:将对象的所有值转成数组合集

Object.prototype.sx_values = function (obj) {

const values = []

for (let key in obj) {

obj.hasOwnProperty(key) && values.push(obj[key])

}

return values

}

console.log(Object.sx_values(obj))

// [ ‘林三心’, 22, ‘男’ ]

43、instanceOf

用处:A instanceOf B,判断A是否经过B的原型链

function instanceOf(father, child) {

const fp = father.prototype

var cp = child.proto

while (cp) {

if (cp === fp) {

return true

}

cp = cp.proto

}

return false

}

function Person(name) {

this.name = name

}

const sx = new Person(‘林三心’)

console.log(instanceOf(Person, sx)) // true

console.log(instanceOf(Person, sx2)) // false

44、is

用处:Object.is(a, b),判断a是否等于b

Object.prototype.sx_is = function (x, y) {

if (x === y) {

// 防止 -0 和 +0

return x !== 0 || 1 / x === 1 / y

}

// 防止NaN

return x !== x && y !== y

}

const a = { name: ‘林三心’ }

const b = a

const c = { name: ‘林三心’ }

console.log(Object.sx_is(a, b)) // true

console.log(Object.sx_is(a, c)) // false

45、Object.assign

难点

  • assign接收多个对象,并将多个对象合成一个对象

  • 这些对象如果有重名属性,以后来的对象属性值为准

  • assign返回一个对象,这个对象 === 第一个对象

Object.prototype.sx_assign = function (target, …args) {

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

throw new TypeError(‘Cannot convert undefined or null to object’)

}

target = Object(target)

for (let nextObj of args) {

for (let key in nextObj) {

nextObj.hasOwnProperty(key) && (target[key] = nextObj[key])

}

}

return target

}

const testa = { name: ‘林三心’ }

const testb = { name: ‘sunshine_lin’, age: 22 }

const testc = { age: 18, gender: ‘男’ }

const testd = Object.sx_assign(testa, testb, testc)

console.log(testd) // { name: ‘sunshine_lin’, age: 18, gender: ‘男’ }

console.log(testa === testd) // true

Function篇


46、call

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

obj = obj || window

// Symbol是唯一的,防止重名key

const fn = Symbol()

obj[fn] = this

// 执行,返回执行值

return objfn

}

const testobj = {

name: ‘林三心’,

testFn(age) {

console.log(${this.name}${age}岁了)

}

}

const testobj2 = {

name: ‘sunshine_lin’

}

testobj.testFn.sx_call(testobj2, 22) // sunshine_lin22岁了

47、apply

Function.prototype.sx_apply = function (obj, args) {

obj = obj || window

// Symbol是唯一的,防止重名key

const fn = Symbol()

obj[fn] = this

// 执行,返回执行值

return objfn

}

const testobj = {

name: ‘林三心’,

testFn(age) {

console.log(${this.name}${age}岁了)

}

}

const testobj2 = {

name: ‘sunshine_lin’

}

testobj.testFn.sx_apply(testobj2, [22]) // sunshine_lin22岁了

48、Function.prototype.bind

难点:

  • bind是返回一个函数,而不是执行结果

  • bind返回的函数,拿来当做构造函数,该怎么处理

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

obj = obj || window

// Symbol是唯一的,防止重名key

const fn = Symbol()

obj[fn] = this

const _this = this

const res = function (…innerArgs) {

console.log(this, _this)

if (this instanceof _this) {

this[fn] = _this

this[fn](…[…args, …innerArgs])

delete this[fn]

} else {

obj[fn](…[…args, …innerArgs])

delete obj[fn]

}

}

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

return res

}

String篇


49、slice

参数代表含义

  • start:开始截取的字符索引(包含此字符)

  • end:结束截取的字符索引(不包含此字符)

注意点

  • start > end:返回空字符串

  • start < 0:start = 数组长度 + start

String.prototype.sx_slice = function (start = 0, end) {

start = start < 0 ? this.length + start : start

end = !end && end !== 0 ? this.length : end

if (start >= end) return ‘’

let str = ‘’

for (let i = start; i < end; i++) {

str += this[i]

}

return str

}

console.log(str.sx_slice(2)) // nshine_lin

console.log(str.sx_slice(-2)) // in

console.log(str.sx_slice(-9, 10)) // shine_l

console.log(str.sx_slice(5, 1)) // ‘’

50、substr

参数代表含义

  • start:开始截取的字符索引(包含此字符)

  • length:截取的长度

注意点

  • start < 0:start = 数组长度 + start

  • length超出所能截取范围,需要做处理

  • length < 0:返回空字符串

String.prototype.sx_substr = function (start = 0, length) {

if (length < 0) return ‘’

start = start < 0 ? this.length + start : start

length = (!length && length !== 0) || length > this.length - start ? this.length : start + length

let str = ‘’

for (let i = start; i < length; i++) {

str += this[i]

}

return str

}

console.log(str.sx_substr(3)) // shine_lin

console.log(str.sx_substr(3, 3)) // shi

console.log(str.sx_substr(5, 300)) // ine_lin

51、substring

功能与slice大致相同

区别之处

  • start > end:互换值

String.prototype.sx_sunstring = function (start = 0, end) {

start = start < 0 ? this.length + start : start

end = !end && end !== 0 ? this.length : end

if (start >= end) [start, end] = [end, start]

let str = ‘’

for (let i = start; i < end; i++) {

str += this[i]

}

return str

}

console.log(str.sx_sunstring(2)) // nshine_lin

console.log(str.sx_sunstring(-2)) // in

console.log(str.sx_sunstring(-9, 10)) // shine_l

console.log(str.sx_sunstring(5, 1)) // unsh

Promise篇


52、all

  • 接收一个Promise数组,数组中如有非Promise项,则此项当做成功

  • 如果所有Promise都成功,则返回成功结果数组

  • 如果有一个Promise失败,则返回这个失败结果

function all(promises) {

const result = []

let count = 0

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

const addData = (index, value) => {

result[index] = value

count++

if (count === promises.length) resolve(result)

}

promises.forEach((promise, index) => {

if (promise instanceof MyPromise) {

promise.then(res => {

addData(index, res)

}, err => reject(err))

} else {

addData(index, promise)

}

})

})

}

53、race

  • 接收一个Promise数组,数组中如有非Promise项,则此项当做成功

  • 哪个Promise最快得到结果,就返回那个结果,无论成功失败

function race(promises) {

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

promises.forEach(promise => {

if (promise instanceof MyPromise) {

promise.then(res => {

resolve(res)

}, err => {

reject(err)

})

} else {

resolve(promise)

}

})

})

}

54、allSettled

  • 接收一个Promise数组,数组中如有非Promise项,则此项当做成功

  • 把每一个Promise的结果,集合成数组,返回

function allSettled(promises) {

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

const res = []

let count = 0

const addData = (status, value, i) => {

res[i] = {

status,

value

}

count++

if (count === promises.length) {

resolve(res)

}

}

promises.forEach((promise, i) => {

if (promise instanceof MyPromise) {

promise.then(res => {

addData(‘fulfilled’, res, i)

}, err => {

addData(‘rejected’, err, i)

})

} else {

addData(‘fulfilled’, promise, i)

}

})

})

}

55、any

any与all相反

  • 接收一个Promise数组,数组中如有非Promise项,则此项当做成功

  • 如果有一个Promise成功,则返回这个成功结果

  • 如果所有Promise都失败,则报错

function any(promises) {

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

let count = 0

promises.forEach((promise) => {

promise.then(val => {

resolve(val)

}, err => {

count++

if (count === promises.length) {

reject(new AggregateError(‘All promises were rejected’))

}

})

})

})

}

}

56、finally

  • 接收一个回调函数,但无参数接收

  • 无论成功失败状态,都会执行finally

Promise.prototype.finally = function(callback) {

return this.then(res => {

callback()

return res

}, err => {

callback()

throw err

})

}

结语

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

img

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

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

完整版面试题资料分享,只需你点赞支持,动动手指点击此处就可免费领取了

前端实习面试的套路


回顾项目

往往在面试时,面试官根据你简历中的项目由点及面地展开问答,所以请对你做过的最好的项目进行回顾和反思。回顾你做过的工作和项目中最复杂的部分,反思你是如何完成这个最复杂的部分的。

面试官会重点问你最复杂的部分的实现方法和如何优化。重点要思考如何优化,即使你项目中没有对那部分进行优化,你也应该预先思考有什么优化的方案。如果这部分答好了,会给面试官留下很不错的印象。

重点在于基础知识

这里指的基础知识包括:前端基础知识和学科基础知识。

前端基础知识:html/css/js 的核心知识,其中 js 的核心知识尤为重要。比如执行上下文、变量对象/活动对象(VO/AO)、作用域链、this 指向、原型链等。

学科基础知识:数据结构、计算机网络、算法等知识。你可能会想前端不需要算法,那你可能就错了,在大公司面试,面试官同样会看重学生这些学科基础知识。
你可能发现了我没有提到React/Vue这些框架的知识,这里得说一说,大公司不会过度的关注这方面框架的知识,他们往往更加考察学生的基础。
这里我的建议是,如果你至少使用或掌握其中一门框架,那是最好的,可以去刷刷相关框架的面试题,这样在面试过程中即使被问到了,也可以回答个 7788。如果你没有使用过框架,那也不需要太担心,把重点放在基础知识和学科基础知识之上,有其余精力的话可以去看看主流框架的核心思想。

ddData(‘rejected’, err, i)

})

} else {

addData(‘fulfilled’, promise, i)

}

})

})

}

55、any

any与all相反

  • 接收一个Promise数组,数组中如有非Promise项,则此项当做成功

  • 如果有一个Promise成功,则返回这个成功结果

  • 如果所有Promise都失败,则报错

function any(promises) {

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

let count = 0

promises.forEach((promise) => {

promise.then(val => {

resolve(val)

}, err => {

count++

if (count === promises.length) {

reject(new AggregateError(‘All promises were rejected’))

}

})

})

})

}

}

56、finally

  • 接收一个回调函数,但无参数接收

  • 无论成功失败状态,都会执行finally

Promise.prototype.finally = function(callback) {

return this.then(res => {

callback()

return res

}, err => {

callback()

throw err

})

}

结语

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

[外链图片转存中…(img-3km3jMUr-1711693348842)]

[外链图片转存中…(img-KAVJsx4I-1711693348842)]

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

[外链图片转存中…(img-DLRc1KYE-1711693348843)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

完整版面试题资料分享,只需你点赞支持,动动手指点击此处就可免费领取了

前端实习面试的套路


回顾项目

往往在面试时,面试官根据你简历中的项目由点及面地展开问答,所以请对你做过的最好的项目进行回顾和反思。回顾你做过的工作和项目中最复杂的部分,反思你是如何完成这个最复杂的部分的。

面试官会重点问你最复杂的部分的实现方法和如何优化。重点要思考如何优化,即使你项目中没有对那部分进行优化,你也应该预先思考有什么优化的方案。如果这部分答好了,会给面试官留下很不错的印象。

重点在于基础知识

这里指的基础知识包括:前端基础知识和学科基础知识。

前端基础知识:html/css/js 的核心知识,其中 js 的核心知识尤为重要。比如执行上下文、变量对象/活动对象(VO/AO)、作用域链、this 指向、原型链等。

学科基础知识:数据结构、计算机网络、算法等知识。你可能会想前端不需要算法,那你可能就错了,在大公司面试,面试官同样会看重学生这些学科基础知识。
你可能发现了我没有提到React/Vue这些框架的知识,这里得说一说,大公司不会过度的关注这方面框架的知识,他们往往更加考察学生的基础。
这里我的建议是,如果你至少使用或掌握其中一门框架,那是最好的,可以去刷刷相关框架的面试题,这样在面试过程中即使被问到了,也可以回答个 7788。如果你没有使用过框架,那也不需要太担心,把重点放在基础知识和学科基础知识之上,有其余精力的话可以去看看主流框架的核心思想。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号