84669 person learning
152542 person learning
20005 person learning
5487 person learning
7821 person learning
359900 person learning
3350 person learning
180660 person learning
48569 person learning
18603 person learning
40936 person learning
1549 person learning
1183 person learning
32909 person learning
具体问题如上图,求大牛点拨。谢谢。
小伙看你根骨奇佳,潜力无限,来学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使用方法