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()`
- 前端入门
- 前端入职须知
- 正确看待前端
- 前端自我定位
- pc与手机页面差别
- 前端书单
- 前端技术栈
- 前端资源导航
- 前端切图
- 插件
- 组件、控件和插件的区别
- 技术文档
- layui
- layer弹框在实际项目中的一些应用
- 前端面试题
- bat面试题库
- 中小公司的leader
- 项目相关
- 职业规划如何
- 前端经典笔试题
- javascript基础(一)
- JavaScript基础二
- JavaScript基础面试题(三)
- JavaScript基础面试题(四)
- JavaScript基础面试题(五)
- JavaScript基础面试题(六)
- JavaScript基础面试题(七)
- JavaScript基础面试题(八)
- JavaScript基础面试题(九)
- JavaScript基础面试题(十)
- dom经典面试题
- 正则表达式
- 史上最难面试题
- 简单算法
- 前端idea
- vsc快速上手指南
- 微信开发者工具
- sublime的使用
- hbuilder入门
- 前端那些事
- 前端的注释该怎么写
- 前端架构师是怎么炼成的
- 细数前端的那些技术大牛
- 前端leader的那些事
- ps
- 图片类型及其区别
- 基本概念及其常用工具
- ps操作技巧
- ps站点资源导航
- ui站点导航
- html
- css
- js
- 插件库
- git教程
- web
- web兼容思想
- ui框架
- 小程序
- 微信专题
- 支付宝专题