具体问题如上图,求大牛点拨。谢谢。
小伙看你根骨奇佳,潜力无限,来学PHP伐。
题目似乎有些问题,{{m.className}},{{user.avatar}}一个前面有m,一个没有,不知道是什么意思,就当做没有处理啦。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p id="template-dom" class="{{className}}"> <p class="user-profile"> <p class="user-avatar"> <img src="{{user.avatar}}"> </p> {{user.name}} </p> </p> <script> var render = (function() { var reg = /{{([^}]*)}}/g /** * 根据prop获取model的某个field * @param model * @param prop * @returns {*} */ function getField(model, prop) { let keys = prop.split('.') for (let key of keys) { if (model[key] == null) { return } else { model = model[key] } } return model } function traverse(el,model){ // 文本节点,替换文本内容 if(el.nodeType == 3 ){ el.textContent = el.textContent.replace(reg,function(word,prop){ return getField(model,prop) }) } else { //非文本节点替换属性内容 var attributes = Array.prototype.slice.call(el.attributes) for (let attr of attributes) { let value = attr.value value = value.replace(reg,function(word,prop){ return getField(model,prop) }) attr.value = value } } /** * 递归替换子节点 * @type {Array.<T>} */ let childNodes = Array.prototype.slice.call(el.childNodes) for(let child of childNodes){ traverse(child,model) } } function render(el,model){ traverse(el,model) } return render; })() </script> <script> var m = { className: 'user', user:{ name: 'wscn', avatar:'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png' } } render(document.getElementById('template-dom'),m) </script> </body> </html>
new Function(arg1, arg2, ..., argN, function_body)
可能不对,大神轻喷。
自己写了个demo, 不知道对不,这里
但我感觉绕来绕去没什么意思,面试题至于这么整吗?
function render(dom, m) { var re = /\{\{(.*)\}\}/g; var outerHTML = dom.outerHTML; var mapper = outerHTML .match(re) .map(v => v.replace(/(\{\{|\}\})/g, '') ) .map(v => { var x; try { x = eval(v); } catch(e) { x = ''; } return x; }); return outerHTML.replace(re, function() { return mapper.shift(); }) }
对不起,我还是用了 eval。原本以为可以用 (new Function('return ' + v))() 之类的替代 eval 的,但实验结果是不可以。另外,没看懂什么叫不允许替换原始 dom ,所以直接输出字符串了。
eval
(new Function('return ' + v))()
最后说一下自己的看法,这类题目平时玩玩还好,真要做面试题?恶心死人了,活该招不到人。
https://segmentfault.com/a/1190000004428...
试着做了一下,很菜....
function render(e,f){ e.className = f.className; var imgObj = e.getElementsByTagName('img')[0]; imgObj.src = f.user.avatar; var obj = e.childNodes; for (var i = 0; i < obj.length; i++) { if(obj[i].className == 'user-profile'){ obj = obj[i]; } }; var o1 = obj.lastChild; var o2 = document.createElement('p'); o2.textContent = f.user.name; console.log(obj.lastChild); obj.replaceChild(o2,o1); }
也来玩一下,同样的感觉没必要加m.,都已经把m对象传入了函数中了。
m.
m
var render = function (dom, obj) { var pattern = /\{\{([^(\})]*)\}\}/g, html = dom.outerHTML, reps = html.match(pattern) .map(val => val.replace(/[\{\{\}\}]/g, "")) .map( (val) => { var keys = val.split("."), res = obj; for (var i of keys) { res = res[i]; } return res; }); dom.outerHTML = html.replace(pattern, () => reps.shift()); };
另外,问下这是哪家公司?
var render = (function(){ function getValue(keyString, o){ var keys = keyString.split("."); return keys.reduce(function(prev, curr){ return prev[curr]; }, o); } var reg = /\{\{([^\}]*)\}\}/g; return function(elem, o){ var html = elem.outerHTML; elem.outerHTML = html.replace(reg, function(match, g){ return getValue(g.trim(), o); }); } })();
不能用eval那就当然是用new Function啦。不过还是第一个答案那样,用对象键名来取值最好JSBin实例
var m = { className: 'user', user:{ name: 'wscn', avatar:'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png' } } var render = function (dom, model) { var reg = /{{([^{}]*)}}/g var attrs = Array.prototype.slice.call(dom.attributes) for (let attr of attrs) { attr.value = attr.value.replace(reg, function (src, val) { return new Function('return ' + val)() }) } var childs = Array.prototype.slice.call(dom.childNodes) for (let child of childs) { if (child.nodeType === 1) { render(child, model) } else if (child.nodeType === 3) { child.nodeValue = child.nodeValue.replace(reg, function (src, val) { return new Function('return ' + val)() }) } } } render(document.getElementById('template-dom'), m)
这是模板页面吧,通过后台程序自动替换内容到页面中的,出题的人不懂技术吧,或者一枝半解,为了效率,功能也不会这样设计的
使用with以及Function应该可以完成这类问题,具体可以参考阮一峰javascript教程with使用方法
with
Function
题目似乎有些问题,{{m.className}},{{user.avatar}}一个前面有m,一个没有,不知道是什么意思,就当做没有处理啦。
new Function(arg1, arg2, ..., argN, function_body)
可能不对,大神轻喷。
自己写了个demo, 不知道对不,这里
但我感觉绕来绕去没什么意思,面试题至于这么整吗?
对不起,我还是用了
eval
。原本以为可以用
(new Function('return ' + v))()
之类的替代eval
的,但实验结果是不可以。另外,没看懂什么叫不允许替换原始 dom ,所以直接输出字符串了。
最后说一下自己的看法,这类题目平时玩玩还好,真要做面试题?
恶心死人了,活该招不到人。
https://segmentfault.com/a/1190000004428...
试着做了一下,很菜....
也来玩一下,同样的感觉没必要加
m.
,都已经把m
对象传入了函数中了。另外,问下这是哪家公司?
不能用eval那就当然是用new Function啦。
不过还是第一个答案那样,用对象键名来取值最好
JSBin实例
这是模板页面吧,通过后台程序自动替换内容到页面中的,出题的人不懂技术吧,或者一枝半解,为了效率,功能也不会这样设计的
使用
with
以及Function
应该可以完成这类问题,具体可以参考阮一峰javascript教程with使用方法