小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停叫唤(yelp)。请根据描述,按示例的形式用代码来实。(继承,原型,setInterval)
答案:
function MadDog() { this.yelp = function() { var self = this; setInterval(function() { self.wow(); }, 500); } } MadDog.prototype = new Dog(); //for test var dog = new Dog(); dog.yelp(); var madDog = new MadDog(); madDog.yelp();
4.下面这个ul,如何点击每一列的时候alert其index?(闭包)
复制代码 代码如下:
<ul id=”test”>
<li>这是第一条</li>
<li>这是第二条</li>
<li>这是第三条</li>
</ul>
答案:
// 方法一: var lis=document.getElementById('2223').getElementsByTagName('li'); for(var i=0;i<3;i++) { lis[i].index=i; lis[i].onclick=function(){ alert(this.index); }; } //方法二: var lis=document.getElementById('2223').getElementsByTagName('li'); for(var i=0;i<3;i++) { lis[i].index=i; lis[i].onclick=(function(a){ return function() { alert(a); } })(i); }
5.编写一个JavaScript函数,输入指定类型的选择器(仅需支持id,class,tagName三种简单CSS选择器,无需兼容组合选择器)可以返回匹配的DOM节点,需考虑浏览器兼容性和性能。
/*** @param selector {String} 传入的CSS选择器。* @return {Array}*/
答案:(过长,点击打开)
var query = function(selector) { var reg = /^(#)?(\.)?(\w+)$/img; var regResult = reg.exec(selector); var result = []; //如果是id选择器 if(regResult[1]) { if(regResult[3]) { if(typeof document.querySelector === "function") { result.push(document.querySelector(regResult[3])); } else { result.push(document.getElementById(regResult[3])); } } } //如果是class选择器 else if(regResult[2]) { if(regResult[3]) { if(typeof document.getElementsByClassName === 'function') { var doms = document.getElementsByClassName(regResult[3]); if(doms) { result = converToArray(doms); } } //如果不支持getElementsByClassName函数 else { var allDoms = document.getElementsByTagName("*") ; for(var i = 0, len = allDoms.length; i < len; i++) { if(allDoms[i].className.search(new RegExp(regResult[2])) > -1) { result.push(allDoms[i]); } } } } } //如果是标签选择器 else if(regResult[3]) { var doms = document.getElementsByTagName(regResult[3].toLowerCase()); if(doms) { result = converToArray(doms); } } return result; } function converToArray(nodes){ var array = null; try{ array = Array.prototype.slice.call(nodes,0);//针对非IE浏览器 }catch(ex){ array = new Array(); for( var i = 0 ,len = nodes.length; i < len ; i++ ) { array.push(nodes[i]) } } return array; }
6.请评价以下代码并给出改进意见。
if(window.addEventListener){ var addListener = function(el,type,listener,useCapture){ el.addEventListener(type,listener,useCapture); }; } else if(document.all){ addListener = function(el,type,listener){ el.attachEvent("on"+type,function(){ listener.apply(el); }); } }
评价:
•不应该在if和else语句中声明addListener函数,应该先声明;
•不需要使用window.addEventListener或document.all来进行检测浏览器,应该使用能力检测;
•由于attachEvent在IE中有this指向问题,所以调用它时需要处理一下
改进如下:
function addEvent(elem, type, handler){ if(elem.addEventListener){ elem.addEventListener(type, handler, false); }else if(elem.attachEvent){ elem['temp' + type + handler] = handler; elem[type + handler] = function(){ elem['temp' + type + handler].apply(elem); }; elem.attachEvent('on' + type, elem[type + handler]); }else{ elem['on' + type] = handler; } }
7.给String对象添加一个方法,传入一个string类型的参数,然后将string的每个字符间价格空格返回,例如:
addSpace("hello world") // -> 'h e l l o w o r l d'
复制代码 代码如下:
String.prototype.spacify = function(){
return this.split('').join(' ');
};
接着上述答题,那么问题来了
1)直接在对象的原型上添加方法是否安全?尤其是在Object对象上。(这个我没能答出?希望知道的说一下。)
2)函数声明与函数表达式的区别?
答案:在Javscript中,解析器在向执行环境中加载数据时,对函数声明和函数表达式并非是一视同仁的,解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问),至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行。(函数声明提升)
8.定义一个log方法,让它可以代理console.log的方法。
可行的方法一:
复制代码 代码如下:
function log(msg) {
console.log(msg);
}
log("hello world!") // hello world!
如果要传入多个参数呢?显然上面的方法不能满足要求,所以更好的方法是:
复制代码 代码如下:
function log(){
console.log.apply(console, arguments);
};
那么问题来了,apply和call方法的异同?
答案: