We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
// base.js let count = 0; setTimeout(() => { console.log("base.count", ++count); }, 500) module.exports.count = count; // �commonjs.js const { count } = require('./base'); setTimeout(() => { console.log("count is" + count + 'in commonjs'); }, 1000) // base1.js let count = 0; setTimeout(() => { console.log("base.count", ++count); }, 500) exports const count = count; // es6.js import { count } from './base1'; setTimeout(() => { console.log("count is" + count + 'in es6'); }, 1000)
解析:
详细分析请看 《require和import的区别》
console.log((function() { console.log(1); setTimeout(function() { console.log(2) }, 1000) setTimeout(function() { console.log(3) }, 0); setTimeout(function() { console.log(4) }, 0); console.log(5) })());
详细分析请看 《setTimeout和requestAnimationFrame》
console.log((typeof null )); console.log((typeof [])); console.log((typeof Symbol())); console.log((typeof 123n) ); function foo() { console.log(111); }; console.log((typeof foo));
function *foo(x) { const y = 2 * (yield (x + 1)); const z = yield (y / 3); return (x + y + z); } const a = foo(5); console.log(a.next()); console.log(a.next()); console.log(a.next()); const b = foo(5); console.log(b.next()); console.log(b.next(12)); console.log(b.next(13));
#### 答案:
{ value: 6, done: false } { value: NaN, done: false } { value: NaN, done: true } { value: 6, done: false } { value: 8, done: false } { value: 42, done: true }
解析: 先看使用Generator函数生成的迭代器a:
a
第一次调用next方法,遇到 yield 停止,返回yield表达式的值,此时为 5 + 1 = 6;
5 + 1 = 6
第二次调用next方法,遇到 yield 停止,返回yield表达式的值,由于next方法没有带参数,上一个yield表达式返回值为undefined, 导致y的值等于2*undefined即(NaN),除以 3 以后还是NaN,因此返回对象的value属性也等于NaN。
undefined
y
2*undefined
NaN
3
value
第三次调用next方法,执行的是 return (x + y + z),此时x的值为 5, y的值为 NaN, 由于next方法没有带参数,上一个yield表达式返回值为undefined,导致z为 undefined,返回对象的 value属性等于5 + NaN + undefined,即 NaN
return (x + y + z)
x
5
5 + NaN + undefined
再来看看使用Generator函数生成的迭代器b:
b
第二次调用next方法,遇到 yield 停止,返回yield表达式的值,由于next方法带有参数12,所以上一个yield表达式返回值为12, 因此y的值等于2*12即(24),除以 3 是8,因此返回对象的value属性为8。
12
2*12
24
8
第三次调用next方法,执行的是 return (x + y + z),此时x的值为 5, y的值为 24, 由于next方法没有带参数13,因此z为13,返回对象的 value属性等于5 + 24 + 13,即 42
13
5 + 24 + 13
42
详细分析请看 Generator函数�详解》
let z = 1; function *foo() { const x = yield 2; z++; const y = yield (x * z); console.log(x, y, z); } const a = foo(); const b = foo(); let val1 = a.next().value; console.log(val1); let val2 = b.next().value; console.log(val2); val1 = a.next(val2 * 10).value; console.log(val1); val2 = b.next(val1 * 5).value; console.log(val2); a.next(val2 / 2); b.next(val1 / 4);
解析
*foo()的两个实例同时启用,两个next() 分别从yield 2 语句得到2
*foo()
next()
yield 2
2
val2 * 10 也就是2 * 10,发送到第一个生成器实例 a, 因为x得到的值20。z从1增加到2,然后 20 * 2通过 yield发出,将val1设置为40
val2 * 10
2 * 10
20
z
1
20 * 2
yield
val1
40
val1 * 5 也就是 40 * 5,发送到第二个生成器实例 b,因此x得到的值200。z再从 2递增到3,然后 200*3通过 yield 发出,将val2设置为 600
val1 * 5
40 * 5
200
200*3
val2
600
val2 / 2 也就是 600 / 2 发动到第一个生成器实例 a, 因此 y得到值 300, 然后打印出 x y z 的值分别为 20, 300, 3。
val2 / 2
600 / 2
300
x y z
20, 300, 3
val1 / 4 也就是 40 / 4, 发送到第二个生成器实例 b, 因此 y得到的值10, 然后打印出 x y z的值分别为 200, 10, 3。
val1 / 4
40 / 4
10
200, 10, 3
详细分析请看 《Generator函数》
JavaScript有八种内置类型 1. 空值(null) 2. 未定义(undefined) 3. 布尔值(boolean) 4. 数字(number) 5. 字符串(string) 6. 对象 (object) 7. 符号(symbol, ES6中新增) 7. 大整数(BigInt, ES2020 引入)
除对象外,其他统称为“基本类型”。
注意新增的 symbol和 BigInt
symbol
BigInt
typeof原理: 不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息。
typeof
typeof null 为"object", 原因是因为 不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位都为0的话会被判断为Object类型,null的二进制表示全为0,自然前三位也是0,所以执行typeof时会返回"object"。
关键词:JavaScript数据类型的相关底层机制
instanceof的语法:
instanceof
object instanceof constructor // 等同于 constructor.prototype.isPrototypeOf(object)
instanceof原理: 检测 constructor.prototype是否存在于参数 object的 原型链上。instanceof 查找的过程中会遍历object 的原型链,直到找到 constructor 的 prototype ,如果查找失败,则会返回false,告诉我们,object 并非是 constructor 的实例。
constructor.prototype
object
constructor
prototype
false
对象的Symbol.hasInstance属性,指向一个内部方法。当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法。比如,foo instanceof Foo在语言内部,实际调用的是FooSymbol.hasInstance。
Symbol.hasInstance
foo instanceof Foo
class MyClass { [Symbol.hasInstance](foo) { return foo instanceof Array; } } [1, 2, 3] instanceof new MyClass() // true
关键词:instanceof 用法,原型链,Symbol.hasInstance。详细分析请查看《 typeof和instanceof原理》
setTimeout(function fn(){ console.log('我被调用了'); setTimeout(fn, 100); },100);
setTimeout(()=> {}, 0)
执行该语句时,是立即把当前定时器代码推入事件队列,当定时器在事件列表中满足设置的时间值时将传入的函数加入任务队列,之后的执行就交给任务队列负责。但是如果此时任务队列不为空,则需等待,所以执行定时器内代码的时间可能会大于设置的时间。
HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔)不得低于4毫秒。 当指定的时间低于该时间时,浏览器会用最小允许的时间作为setTimeout的时间间隔,也就是说即使我们把setTimeout的延迟时间设置为0,实际上可能为 4毫秒后才事件推入任务队列。
requestAnimationFrame
requestIdleCallback()
for...of 不只是用来遍历数组的,只要有iterator 接口的数据结构都可以用它来遍历。一个数据结构只要部署了Symbol.iterator属性,就被视为具有 iterator 接口。iterator的实现思想来源于 单向链表。
iterator
Symbol.iterator
单向链表
关键词:iterator, Symbol.iterator, 单向链表。详细分析请看 《for...of原理解析》
function makeIterator(array) { var nextIndex = 0; return { next: function() { return nextIndex < array.length ? { value: array[nextIndex++], done: false } : { value: undefined, done: true }; } }; } const it = makeIterator(['a', 'b']); it.next() // { value: "a", done: false } it.next() // { value: "b", done: false } it.next() // { value: undefined, done: true }
暂停执行(yield)
恢复执行(next)
函数体内外的数据交换
next
向外输出
参数
向内输入
错误处理机制
更多请查看 Generator函数详解》
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
示例 1:
输入: [7,1,5,3,6,4] 输出: 5 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:
输入: [7,6,4,3,1] 输出: 0 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
答案: 买卖股票的最佳时机
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
输入: [7,1,5,3,6,4] 输出: 7 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
输入: [1,2,3,4,5] 输出: 4 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:
答案: 《买卖股票的最佳时机》
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例:
输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4
答案:合并两个有序链表
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例:
输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
答案:最大子序和
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
示例 1: 输入: [1,2,3,4,5] 输出: True 示例 2: 输入: [0,0,1,2,5] 输出: True
限制: 1.数组长度为 5 2.数组的数取值为 [0, 13] .
答案:扑克牌中的顺子
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
答案:无重复字符的最长子串
最新发起了一个100天前端进阶计划,致力于弄明白每个知识点背后的原理。这是第一周的总结,本来想直接粘贴一下原先的标题并附上原文链接。后来想还是找几道关于本周内容的一些面试题(大部分为原文中的例子),方便检测一下自己的掌握程度。一共20道,看看自己能得几分。算法题做多要在半个小时之内写出最优解,上面提供的答案并一定是最好的,如果有问题或者更好的解法欢迎大家留言指出。或者你最新碰到的类似的面试题,也可以提供给我进行补充。
最近发起了一个100天前端进阶计划,主要是深挖每个知识点背后的原理,欢迎关注微信公众号「牧码的星星」,我们一起学习,打卡100天。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
目录
笔试题
1.下面代码输出什么
答案
答案:1,0,1,1
解析:
2.下面代码输出什么
答案
答案:1, 5, undefined, 3, 4, 2
3.下面代码输出什么
答案
答案:
4.下面代码输出什么
答案
#### 答案:
解析:
先看使用Generator函数生成的迭代器
a
:第一次调用next方法,遇到 yield 停止,返回yield表达式的值,此时为
5 + 1 = 6
;第二次调用next方法,遇到 yield 停止,返回yield表达式的值,由于next方法没有带参数,上一个yield表达式返回值为
undefined
, 导致y
的值等于2*undefined
即(NaN
),除以3
以后还是NaN
,因此返回对象的value
属性也等于NaN
。第三次调用next方法,执行的是
return (x + y + z)
,此时x
的值为5
,y
的值为NaN
, 由于next方法没有带参数,上一个yield表达式返回值为undefined
,导致z为 undefined,返回对象的 value属性等于5 + NaN + undefined
,即 NaN再来看看使用Generator函数生成的迭代器
b
:第一次调用next方法,遇到 yield 停止,返回yield表达式的值,此时为
5 + 1 = 6
;第二次调用next方法,遇到 yield 停止,返回yield表达式的值,由于next方法带有参数
12
,所以上一个yield表达式返回值为12
, 因此y
的值等于2*12
即(24
),除以3
是8
,因此返回对象的value
属性为8
。第三次调用next方法,执行的是
return (x + y + z)
,此时x
的值为5
,y
的值为24
, 由于next方法没有带参数13
,因此z为13
,返回对象的 value属性等于5 + 24 + 13
,即42
5.下面代码输出什么
答案
答案:
解析
*foo()
的两个实例同时启用,两个next()
分别从yield 2
语句得到2
val2 * 10
也就是2 * 10
,发送到第一个生成器实例a
, 因为x得到的值20
。z
从1
增加到2
,然后20 * 2
通过yield
发出,将val1
设置为40
val1 * 5
也就是40 * 5
,发送到第二个生成器实例b
,因此x得到的值200
。z
再从2
递增到3
,然后200*3
通过yield
发出,将val2
设置为600
val2 / 2
也就是600 / 2
发动到第一个生成器实例a
, 因此 y得到值300
, 然后打印出x y z
的值分别为20, 300, 3
。val1 / 4
也就是40 / 4
, 发送到第二个生成器实例b
, 因此y
得到的值10
, 然后打印出x y z
的值分别为200, 10, 3
。简答题
1. commonjs模块和ES6模块的区别
答案
2. JS有哪几种数据类型
答案
JavaScript有八种内置类型 1. 空值(null) 2. 未定义(undefined) 3. 布尔值(boolean) 4. 数字(number) 5. 字符串(string) 6. 对象 (object) 7. 符号(symbol, ES6中新增) 7. 大整数(BigInt, ES2020 引入)
除对象外,其他统称为“基本类型”。
3. typeof 原理是什么
答案
typeof
原理: 不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息。typeof null 为"object", 原因是因为 不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位都为0的话会被判断为Object类型,null的二进制表示全为0,自然前三位也是0,所以执行typeof时会返回"object"。
4. instanceof 原理是什么,自己可以自定义一个么
答案
instanceof
的语法:instanceof
原理: 检测constructor.prototype
是否存在于参数 object的 原型链上。instanceof
查找的过程中会遍历object
的原型链,直到找到constructor
的prototype
,如果查找失败,则会返回false
,告诉我们,object
并非是constructor
的实例。对象的
Symbol.hasInstance
属性,指向一个内部方法。当其他对象使用instanceof
运算符,判断是否为该对象的实例时,会调用这个方法。比如,foo instanceof Foo
在语言内部,实际调用的是FooSymbol.hasInstance。5. setTimeout和setInterval 区别是什么,怎么用 setTimeout实现 setInterval
答案
6. 怎么理解
setTimeout(()=> {}, 0)
答案
执行该语句时,是立即把当前定时器代码推入事件队列,当定时器在事件列表中满足设置的时间值时将传入的函数加入任务队列,之后的执行就交给任务队列负责。但是如果此时任务队列不为空,则需等待,所以执行定时器内代码的时间可能会大于设置的时间。
HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔)不得低于4毫秒。 当指定的时间低于该时间时,浏览器会用最小允许的时间作为setTimeout的时间间隔,也就是说即使我们把setTimeout的延迟时间设置为0,实际上可能为 4毫秒后才事件推入任务队列。
7. requestAnimationFrame是什么,有什么应用场景, requestIdleCallback是什么,有什么应用场景
答案
requestAnimationFrame
是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘。requestIdleCallback()
常用来切割长任务,利用空闲时间执行,避免主线程长时间阻塞。8. for...of 原理是什么?
答案
for...of 不只是用来遍历数组的,只要有
iterator
接口的数据结构都可以用它来遍历。一个数据结构只要部署了Symbol.iterator
属性,就被视为具有iterator
接口。iterator
的实现思想来源于单向链表
。9. 自己实现一个迭代器?
答案
10. Gennrator哪些特性决定它可以解决异步?
答案
暂停执行(yield)
和恢复执行(next)
函数体内外的数据交换
(next
返回值的value
,是向外输出
数据,next
方法的参数
,是向内输入
数据)和错误处理机制
(Generator 函数内部还可以部署错误处理代码,捕获函数体外抛出的错误)算法题
1. 买卖股票的最佳时机I
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
示例 1:
示例 2:
答案: 买卖股票的最佳时机
2. 买卖股票的最佳时机II
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
示例 2:
示例 3:
答案: 《买卖股票的最佳时机》
3. 合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
答案:合并两个有序链表
4. 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
答案:最大子序和
5.扑克牌中的顺子
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
限制:
1.数组长度为 5
2.数组的数取值为 [0, 13] .
答案:扑克牌中的顺子
6.无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
示例 2:
示例 3:
答案:无重复字符的最长子串
碎碎念
最新发起了一个100天前端进阶计划,致力于弄明白每个知识点背后的原理。这是第一周的总结,本来想直接粘贴一下原先的标题并附上原文链接。后来想还是找几道关于本周内容的一些面试题(大部分为原文中的例子),方便检测一下自己的掌握程度。一共20道,看看自己能得几分。算法题做多要在半个小时之内写出最优解,上面提供的答案并一定是最好的,如果有问题或者更好的解法欢迎大家留言指出。或者你最新碰到的类似的面试题,也可以提供给我进行补充。
其他
最近发起了一个100天前端进阶计划,主要是深挖每个知识点背后的原理,欢迎关注微信公众号「牧码的星星」,我们一起学习,打卡100天。
The text was updated successfully, but these errors were encountered: