阿里前端面试题(1)——解构/异步/markdown语法解析

2.25

1. 对于解构以下说法错误的是:(单选)

a. 不完全解构,也会成功,不会报错
b. 只要支持 Iterator 接口,都可以被解构赋值
c. null 可以替代默认值,而成功的解构赋值
d. 解构中不定参数可以出现在除第一个以外的其他位置
e. 解构是先找到同名属性,然后再赋给对应的变量
f. 默认值可以引用解构赋值的其他变量,但该变量必须已经声明

(d)

  1. 解构
let obj = { name: "xiaoming", age: "10" };
let {name,age} = obj;
console.log(name,age) //xiaoming 10
  1. iterator

迭代一个对象的属性

var a = {
  x: 10,
  y: 20,
};
var iter = Iterator(a);
console.log(iter.next()); // ["x", 10]
console.log(iter.next()); // ["y", 20]
console.log(iter.next()); // throws StopIteration
  1. 不定参数

不定参数只能放在最后一个位置

let obj = { name: "xiaoming", age: "10",height:"175" };
let {...attr} = obj;
console.log(attr) // xiaoming 10 175

//let {...attr,x} = obj //SyntaxError: Rest element must be last element


2. 以下关于异步的说法正确的是:(多选)

a. 在JavaScript中,任务被分为两种,一种宏任务(MacroTask),一种叫微任务(MicroTask),setTimeout 属于微任务
b. setTimeout(func, 500) 会精确的在 500ms 后执行 func
c. Promise、generator、async/await 都是异步解决方案
d. process.nextTick、Promise 都属于 node 中的微队列
e. 浏览器的 Event Loop 和 node 的 Event Loop 是不同的,实现机制也不一样
f. 在 node 中setTimeout 和 setImmediate 执行阶段是一致的

(c,d,e)
解析:f 两者的执行顺序要根据当前的执行环境才能确定

  1. Event Queue


  • 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
  • 当指定的事情完成时,Event Table会将这个函数移入Event Queue。
  • 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
  • 上述过程会不断重复,也就是常说的Event Loop(事件循环)。

(那怎么知道主线程执行栈为空啊?js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数)

  1. 宏任务和微任务
  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

https://juejin.im/post/59e85eebf265da430d571f89

3. 编程题:

Markdown 是非常受技术人员喜欢的一种文本格式,请使用 JavaScript 来实现 marked 方法来进行 markdown 文本的 HTML 渲染,可以满足以下需求:

function marked(str) {
// your code here
}

marked('@@whatever@@').trim() // <p><blink>whatever</blink></p >
marked('abc @@def@@ ghi').trim() // <p><em>abc</em> <blink>def</blink> <strong>ghi</strong></p >
marked('@@cool@@').trim() // <p><blink><strong>cool</strong></blink></p >

可以实现题目中的要求,但是还不能满足“@@abc”这样缺少对应字符串的情况

function marked(str) {
  let stack = [];
  let resultStr = "";
  let currStr = "";
  let i = 0;
  while (i < str.length) {
    let char = str[i];
    switch (char) {
      case "@":
        if (i < str.length - 1 && str[i + 1] === "@") {
          //判断栈的顶部是否有@@
          if (stack[stack.length - 1] === "@@") {
            stack.pop("@@");
            let markedStr = "<blink>" + currStr + "</blink>";
            //判断栈有没有空
            if (stack.length === 0) {
              resultStr += markedStr;
              currStr = "";
            } else {
              currStr = markedStr;
            }
          } else {
            stack.push("@@");
          }
          i++;
        } else {
          currStr += char;
        }
        break;

      case "*":
        if (i < str.length - 1 && str[i + 1] === "*") {
          //判断栈的顶部是否有*
          if (stack[stack.length - 1] === "**") {
            stack.pop("**");
            let markedStr = "<strong>" + currStr + "</strong>";
            //判断栈有没有空
            if (stack.length === 0) {
              resultStr += markedStr;
              currStr = "";
            } else {
              currStr = markedStr;
            }
          } else {
            stack.push("**");
          }
          i++;
        } else if (stack[stack.length - 1] === "*") {
          stack.pop("*");
          let markedStr = "<em>" + currStr + "</em>";
          //判断栈有没有空
          if (stack.length === 0) {
            resultStr += markedStr;
            currStr = "";
          } else {
            currStr = markedStr;
          }
        } else {
          stack.push("*");
        }
        break;

      default:
        currStr += char;
    }
    i++;
  }
  return "<p>" + resultStr + currStr + "</p>";
}
console.log(marked('*abc* @@def@@').trim()); //<p><em>abc</em><blink> def</blink></p>
console.log(marked('@@**cool**@@').trim()); //<p><blink><strong>cool</strong></blink></p>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。