阿里校招前端笔试题小结
来源:互联网 发布:财新数据 编辑:程序博客网 时间:2024/05/21 06:53
阿里前端笔试题,题目不多,难度也不大,我只记录了两道稍微有点难度的编程题。题目如下:
1.JSON.stringify 的功能是,将一个 JavaScript 字面量对象转化为一个 JSON 格式的字符串。例如
const obj = {a:1, b:2}JSON.stringify(obj) // => '{"a":1,"b":2}'
当要转化的对象有“环”存在时(子节点属性赋值了父节点的引用),为了避免死循环,JSON.stringify 会抛出异常,例如:
const obj = { foo: { name: 'foo', bar: { name: 'bar' baz: { name: 'baz', aChild: null // 待会将指向obj.bar } } }}obj.foo.bar.baz.aChild = obj.foo // foo->bar->baz->aChild->foo形成环JSON.stringify(obj) // => TypeError: Converting circular personucture to JSON
请完善以下“环”检查器函数 cycleDetector,当入参对象中有环时返回 true,否则返回 false。
function cycleDetector(obj) { // 请添加代码}
解题思路:首先很容易想到要遍历这个对象,然后判断属性值是否为一个对象,如果是,则递归遍历这个属性值,但难点是该如何判断这个属性值是否为某个父节点的引用,要怎样拿到父节点的引用呢???
其实我们可以先用一个数组cache用来保存对象类型的属性值,再用一个标记变量来标记是否有环,然后遍历时判断这个属性值类型是否为一个对象,如果是,则判断这个属性值是否在那个cache数组里,如果在,则表明有环,如果不在,则把这个属性值添加到数组里,再递归遍历这个属性值即可。
具体代码如下:
function cycleDetector(obj) {let hasCircle = false, //用一个变量去标记是否有环cache = []; //保存值为对象的属性值(function(obj) {Object.keys(obj).forEach(key => {const value = obj[key]if (typeof value == 'object' && value !== null) {const index = cache.indexOf(value)if (index !== -1) { //如果cache中存在这个value,则表示有环hasCircle = truereturn} else {cache.push(value)arguments.callee(value)}}})})(obj)return hasCircle}
2.实现一个EventEmitter类,这个类包含以下方法:
on(监听事件,该事件可以被触发多次)
once(也是监听事件,但只能被触发一次)
fire(触发指定的事件)
off(移除指定事件的某个回调方法或者所有回调方法)
class EventEmitter { /**请补充你的代码***/}const event = new EventEmitter()const drank = (person) => { console.log(person + '喝水')}event.on('drank', drank)event.on('eat', (person) => { console.log(person + '吃东西')})event.once('buy', (person) => { console.log(person + '买东西')})event.fire('drank', '我') // 我喝水 event.fire('drank', '我') // 我喝水 event.fire('eat', '其它人') // 其它人吃东西event.fire('eat', '其它人') // 其它人吃东西event.fire('buy', '其它人') //其它人买东西event.fire('buy', '其它人') //这里不会再次触发buy事件,因为once只能触发一次event.off('eat') //移除eat事件event.fire('eat', '其它人') //这里不会触发eat事件,因为已经移除了
解题思路:这题其实就是实现发布-订阅模式了,难点在于怎样实现once事件,即只触发一次。其实也就是要实现两种类型的事件,我们可以用不同的对象去保存这两种类型的事件,然后在fire的时候,这两种事件都要被处理即可。
具体代码如下:
class EventEmitter {constructor() {this.queue = {} //可触发多次的事件this.onceQueue = {} //只能触发一次的事件}on(event, fn) { //监听事件,可以触发多次if (!this.queue[event]) this.queue[event] = []this.queue[event].push(fn)}once(event, fn) { //监听事件,只能触发一次if (!this.onceQueue[event]) {this.onceQueue[event] = {fns: [],hasFired: false}}this.onceQueue[event].fns.push(fn)}fire() { //触发指定的事件const event = [].shift.call(arguments), //取得事件名称fns = this.queue[event], //取得该事件里所有的回调函数(可以触发多次的事件)onceFns = this.onceQueue[event] //取得该事件里所有的回调函数(只能触发一次的事件)if (fns && fns.length != 0) {let i = 0,fnwhile (fn = fns[i++]) {fn.apply(this, arguments)}}if (onceFns && !onceFns.hasFired) {let i = 0,fnwhile (fn = onceFns.fns[i++]) {fn.apply(this, arguments)}this.onceQueue[event].hasFired = true}}off(event, fn = null) { //可移除特定事件里的某个回调函数或者所有回调函数const fns = this.queue[event]if (!fns || fns.length == 0) returnif (fn) { //移除该事件特定的回调this.queue[event] = fns.filter(item => {return item !== fn})} else { //移除该事件所有的回调this.queue[event] = []}}}
阅读全文
0 0
- 阿里校招前端笔试题小结
- 阿里校招前端笔试题小结
- 阿里校招笔试题
- 阿里招聘前端笔试题小结
- 阿里校招笔试
- 2015 阿里校招 Web前端开发 在线笔试总结
- 阿里2014校招笔试题
- 阿里2018校招笔试编程题
- 阿里前端笔试题
- 阿里前端笔试题
- 阿里前端2018秋招笔试题:判断JSON对象是否有环
- [阿里笔试] 2016阿里校招业务性产品经理(商业领域)笔试题
- 九月十月 阿里 百度 华为 校招笔试题
- 阿里校招 数据分析师 笔试题
- 2017阿里android客户端校招笔试题
- 阿里2018校招客户端研发笔试之编程题
- 2017-08-25阿里校招笔试题---菜鸟仓库
- 2014阿里校招 -- 杂题小结S
- python爬虫笔记之用re及urllib库爬取
- 莫比乌斯反演的学习
- Easyui-tree 文本过长,鼠标悬停显示完整的信息
- 阿里巴巴2018年校招研发C++笔试
- poj3279 Fliptile
- 阿里校招前端笔试题小结
- 在C++中,有哪4个与类型转换相关的关键字?这些关键字有什么特点?应该在什么场合使用?
- poj1182 食物链
- 前端架构变更记
- matlab2c使用c++实现matlab函数系列教程-triu函数
- hessian入门
- new 作用
- 配置SecureCRT密匙登录
- jsday02补充(正则 标签复习回顾)