一、选择题 1. 下列程序运行的结果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 let obj = Object.create({name: 'King'}); function foo(obj){ Object.setPrototypeOf(obj, null); return obj; } console.log(obj === foo(obj)); // true let obj = [1,2,3]; function foo(val){ val = [1,2,3]; return val; } console.log(obj === foo(obj)); // false let obj = 1; function foo(val){ val += 1; return val; } console.log(obj === foo(obj)); // false let obj = {bar: 1}; function foo(val){ val.bar += 1; return val } console.log(obj === foo(obj)); // true let obj = [1,2,3]; function foo(val){ const newVal = val.map(num => num * 2); return newVal; } console.log(obj === foo(obj)); // false let obj = [1,2,3]; function foo(val){ return val.sort(); } console.log(obj === foo(obj)); // true
这里主要考察的引用对象的引用地址是否相同
2. 事件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <body> <div id="J_container"> <div id="div2"> <div id="div1">点我</div> </div> </div> <script> var div1 = document.getElementById('div1'); var div2 = document.getElementById('div2'); div1.addEventListener('click', () => {console.log('a')}, true); div2.addEventListener('click', () => {console.log('b')}); div1.addEventListener('click', () => {console.log('c')}, false); div2.addEventListener('click', () => {console.log('d')}, true); </script> </body>
输出的顺序是: d a c b addEventListener 的第三个参数,是表示事件冒泡还是捕获 点击 div1 之后,事件在 div2 和 div1 处被捕获,打印出 d, a, 之后事件开始向上冒泡,才出现了 c, b
第一道编程题: 要求: 我的答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function cycleDetector(obj){ let stack = []; let res = false; let _incircle = function(item){ let len = stack.length; for( let y = 0; y < len; y++){ if( item === stack[y]){ return true; } } return false; } let _read = function(_obj){ for ( let pro in _obj ){ if( _obj[pro] instanceof Object ){ if ( !_incircle(_obj[pro]) ){ stack.push(_obj[pro]); _read(_obj[pro]); }else{ res = true; } } } }; _read(obj); return res; }
类似与数组去重的思想,遍历这个 obj,如果有存在,就证明存在环
第二道编程题 要求: 我的答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class EventEmitter { /* 在此处填写实现 */ constructor(){ this.eventlist = {}; this.onceEventlist = {}; } fire(obj){ const { type, value } = obj; let _run = 1; let _find = function(list){ for(let i in list){ if(i === type){ for(let j in list[i]){ list[i][j](value); if( _run ){ delete list[i]; } } } } _run = 0; }; _find(this.onceEventlist); _find(this.eventlist); } on(event, fn){ this.eventlist[event] = {}; this.eventlist[event][fn.name] = fn; } off(event, fn){ if(this.eventlist[event]){ delete this.eventlist[event][fn.name]; } } once(event, fn){ this.onceEventlist[event] = {}; this.onceEventlist[event][fn.name] = fn; } } const emitter = new EventEmitter(); const handler = function(evt) { console.log(1, evt); }; emitter.on('foo', handler); emitter.once('foo', function(evt) { console.log(2, evt); }); emitter.fire({ type: 'foo', value: 'hello' }); emitter.fire({ type: 'foo', value: 'world' }); emitter.off('foo', handler); emitter.fire({ type: 'foo', value: 'test' });
一个简易的订阅发布者模式
三、其它 一道模板解析习题 通过正则解析来做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var template = function(str) { var replace = {}; var result; var newStr = str; var re = new RegExp('\\<\\%\\=\\w+\\%\\>','g'); while((result = re.exec(str)) !== null){ var _re = new RegExp('\\w+','g'); var item = result[0].match(_re)[0]; replace[item] = {}; replace[item].origin = result[0]; } return function(obj) { for(var i in obj){ if(replace[i]){ str = str.replace(replace[i].origin, obj[i]); } } return str; } }