多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
1: 把数字转换成中文 完成将 toChineseNum, 可以将数字转换成中文大写的表示,处理到万级别,例如 toChineseNum(12345),返回 一万二千三百四十五。 JavaScript ~~~ const toChineseNum = (num) => { // TODO } ~~~ 答案: ~~~ const toChineseNum = (num) => { const number = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'] // 定义中文数字 const unit = ['', '十', '百', '千', '万'] // 定义中文基 const resultStr = [] let len = 0 // 数字长 let lastNumNotZero = false while(num){ let n = num % 10 let u = len >= unit.length ? len % 5 + 1 : len % 5 // 添加基 if( n // 当前位存在 || // 或者 ( u == unit.length - 1 && // u 和 长度均为 最后一位unit len == unit.length - 1 ) ) resultStr.unshift(unit[u]) // 处理数 if( n || lastNumNotZero // 当前位和前一位不都为零则处理 && u !== unit.length - 1 // 且当前位不为最后一位基 ) resultStr.unshift(number[n]) lastNumNotZero = !!n len++ num = Math.floor(num / 10) } return resultStr.join('') } ~~~ 二: safeGet 有时候我们需要访问一个对象较深的层次,但是如果这个对象某个属性不存在的话就会报错,例如: var data = { a: { b: { c: 'ScriptOJ' } } } data.a.b.c // => scriptoj data.a.b.c.d // => 报错,代码停止执行 console.log('ScriptOJ') // => 不会被执行 请你完成一个 safeGet 函数,可以安全的获取无限多层次的数据,一旦数据不存在不会报错,会返回 undefined,例如: var data = { a: { b: { c: 'ScriptOJ' } } } safeGet(data, 'a.b.c') // => scriptoj safeGet(data, 'a.b.c.d') // => 返回 undefined safeGet(data, 'a.b.c.d.e.f.g') // => 返回 undefined console.log('ScriptOJ') // => 打印 ScriptOJ JavaScript ~~~ const safeGet = (data, path) => { /* TODO */ } ~~~ 答案: ~~~ const safeGet = (o, path) => { try { return path.split('.').reduce((o, k) => o[k], o) } catch (e) { return void 666 } } ~~~ 三: 简单的模版引擎 模版引擎是在前端是非常常用的一种工具。请你完成一个简单的模版引擎的 render 函数,它可以接受模版字符串和一个数据对象作为参数。函数执行返回渲染以后的模版字符串,例如: const templateStr = ` <ul class="users"> <% users.forEach((user) => { %> <li class="user-item"> <%= 'My name is ' + user.name %> </li> <% }) %> </ul> ` const data = { users: [ { name: 'Jerry', age: 12 }, { name: 'Lucy', age: 13 }, { name: 'Tomy', age: 14 } ] } render(templateStr, data) /*返回结果: <ul class="users"> <li class="user-item"> My name is Jerry </li> <li class="user-item"> My name is Lucy </li> <li class="user-item"> My name is Tomy </li> </ul> */ <% 和 %> 之间可以放置任意的 JavaScript 代码,而 <%= 和 %> 之间执行任意的 JavaScript 表达式并且输出在模版上;传入的 data 可以作为模版引擎执行的上下文进行数据的引用,请你完成 render 函数。 (提示:你可以结合 执行任意表达式 来实现) 答案: ~~~ function render(template, data){ const evalExpr = /<%=(.+?)%>/g const expr = /<%([\s\S]+?)%>/g template = template .replace(evalExpr, '`); \n __echo( $1 ); \n __echo(`') .replace(expr, '`); \n $1 \n __echo(`') template = '__echo(`' + template + '`);' const script =` let output = "" const __echo = (html) => output += html ${template} return output ` return new Function(...Object.keys(data), script)(...Object.values(data)) } ~~~ 四: Don't Touch Me Tomy 非常敏感,不喜欢别人碰他的东西。一旦有人碰他就会大喊 Don't Touch Me.。 完成 tomy 这个对象,禁止对 tomy 的内容进行修改(增加、修改、删除)。一旦有人对 tomy 进行任何的修改,都用 console.log 打印 Don't Touch Me.。 答案: ~~~ const tomy = new Proxy({}, { set () { console.log(`Don't Touch Me.`) }, deleteProperty () { console.log(`Don't Touch Me.`) } }) ~~~ 五: 实现 js 数据类型的判断 最新的 Javascript 标准规定了六种基本数据类型(number, null, undefined, string, boolean, symbol) 和基于 Object 衍生的其它原生数据类型,写出 type 函数,它传入一个参数,返回它的数据类型(用小写字母),比如: type(new Date),返回 date。 答案: `const type = (obj) => (({}).toString.call(obj).match(/\[object\ (\w+)\]/)[1]).toLowerCase()`