我最想去的公司啊 -- 幸福面试两小时
面试中,马老师耐心讲解每一道题,让自己也深刻认识到,怎样才算是一个合格的程序员,让别人用着你的代码会很放心。“写代码犹如做人。”很受教,特此与大家一同分享。最深感触,就是代码的严谨性。之前总认为有些JS的小细节不重要,就不往心里记,但最终落实到代码的执行上,则是致命性的。
知识总结:
一、if条件判断方法小结
1,在javascript中,哪些值能作为if的条件呢?
1)布尔变量true/false;
2)数字非0,非NaN/ (0 或NaN);
3)对象非null/(null或undefined)
4)字符串非空串(“”)/空串("")
对于字符串,不用写一大堆if(str!=null && str!=undefined && str !=''), 只要用一句 if(!str){ //do something }
5)对于数字的非空判断,则要考虑使用isNaN()函数,NaN不和任何类型数据相等,包括它本身,只能用isNaN()判断。对于数字类型,if(a)语句中的a为0时if(a)为假,非0时if(a)为真;
2.关于if语句优化的方法 if简写
1 if (foo) bar(); else baz(); ==> foo?bar():baz(); 2 if (!foo) bar(); else baz(); ==> foo?baz():bar(); 3 if (foo) return bar(); else return baz(); ==> return foo?bar():baz();
3.使用and(&&)和or(||)运算符
1 if (foo) bar(); ==> foo&&bar(); 2 if (!foo) bar(); ==> foo||bar();
4.if(x==null)简写
if(x==null)或if (typeof (x) == 'undefined')可以简写为if(!x),未验证。 反之if(x)表示x非空
5.有关NaN的知识点太碎,大家可以访问链接 http://ourjs.com/detail/5383eb8f7610019548000012
二、关于事件对象与事件冒泡
1、事件对象: js的事件对象中保存了当前被触发事件的一些相关的属性信息,如事件源、事件发生时的鼠标位置、事件按键等。
兼容写法: function(e) { var event = window.event || e; }
2、事件源: 事件源即事件发生所在的元素(是最里层元素),在IE中用event.srcElement获取,在Firefox中用event.target获取。
兼容写法: var targetObj = event.srcElement || event.target;
3、事件冒泡:在默认情况下,发生在一个子元素上的单击事件(或者其他事件),如果在其父级元素绑定了一个同样的事件,此时点击子元素,click事件会首先被子元素捕获,执行绑定的事件程序,之后会被父级元素捕获,再次激发一段脚本的执行,这就是所谓的“事件冒泡”。
但有的时候,在一个子元素上处理完单击事件后,不想触发其父元素的相同事件,则需要阻止冒泡的发生。
兼容写法: if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = true; }
4.W3C模型
W3C模型是将两者进行中和,在W3C模型中,任何事件发生时,先从顶层开始进行事件捕获,直到事件触发到达了事件源元素。然后,再从事件源往上进行事件冒泡,直到到达document。
程序员可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。
ele.addEventListener('click',doSomething2,true)
true=捕获
false=冒泡
5.所以,类似链接上的focus或blur事件仅发生于链接自身上,而它的任何父节点上的事件都不会产生,所有不会冒泡,表单事件也不会冒泡。
三、本地存储与cookie
1.我们之前总认为cookie不能跨域访问,其实不然。通过查文档:淘宝就是这么做的。
1)淘宝跨域获取cookie:访问地址 http://developer.51cto.com/art/201104/255729.html
2)sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此 sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
3)HTML5的本地存储是兼容IE8以上,这个我知道的,为啥当时没选对呢?
总结:有关更多本地存储,可以访问链接,介绍与使用方法都介绍特别好:http://blog.csdn.net/fdipzone/article/details/25517615/
四、作用域问题
1 var User = { 2 count: 1, 3 getCount: function() { 4 return this.count; 5 } 6 }; 7 console.log(User.getCount()); 8 var func = User.getCount; 9 console.log(func()); 10 VM2467:7 1 11 VM2467:9 undefined 12 undefined
这里涉及到两个知识点:
1.一般我们都习惯了直接使用 User.getCount()调用;这时的调用者是User,this指向User;
但现在是 var func = User.getCount; 这时func是在winodw的上下文中被执行的,return中的this指向是window,所以会访问不到count属性。
2.如果这里想要访问到count属性怎么办?这时bind方法就很有用了,可以改变this的不同指向。将func改写成这样: var func = User.getCount.bind(User);
就可以将this指向转向User。 有关JavaScript 中的 Function.prototype.bind方法可以访问网址,写的特别好:http://blog.jobbole.com/58032/
五、freeMaker,之前没有认识过
1.获取服务器时间,因为使用JS:freemarker是个模板引擎,她的作用是用来解析你定制的模板,结构是模板加商数据,将数据放入Map中,在ftl模板中来用${name} 来取当中的值,你想在页面获得系统时间,你可以在map中加入一个entry ,key是sysTime,value是new Date(), 然后在页面中用${sysTime?String("yyyy-MM-dd")}来进行系统时间的获得;
2.使用特殊变量 .now ,如:Today is ${.now?date}
总结:有关freeMaker完全陌生,需要抽时间好好看一下。这个网址是freeMaker是使用:http://www.mamicode.com/info-detail-506871.html
六、移动端开发遇到的问题
移动端问题有很多,另辟空间,好好说道说道。
七、原型与数据转换(自我总结)
1.继承:子类继承父类,且不影响父类,也是一种代码复用的方法;
1 //类 : JS是没有类的概念的 , 把JS中的构造函数看做的类 2 3 //要做属性和方法继承的时候,要分开继承 4 5 function Aaa(){ //父类 6 this.name = [1,2,3]; 7 } 8 Aaa.prototype.showName = function(){ 9 alert( this.name ); 10 }; 11 12 function Bbb(){ //子类 13 14 Aaa.call(this); 15 16 } 17 18 var F = function(){}; 19 F.prototype = Aaa.prototype; 20 Bbb.prototype = new F(); 21 Bbb.prototype.constructor = Bbb; //修正指向问题 22 23 var b1 = new Bbb(); 24 //b1.showName(); 25 //alert( b1.name ); 26 //alert( b1.constructor ); 27 b1.name.push(4); 28 29 var b2 = new Bbb(); 30 31 alert( b2.name );
1 var a = { 2 name : '小明' 3 }; 4 5 var b = cloneObj(a); 6 7 b.name = '小强'; 8 9 //alert( b.name ); 10 alert( a.name ); 11 12 function cloneObj(obj){ 13 14 var F = function(){}; 15 16 F.prototype = obj; 17 18 return new F(); 19 20 }
拷贝继承: 通用型的 有new或无new的时候都可以
类式继承: new构造函数
原型继承: 无new的对象
1 function Aaa( )= {}; Aaa.prototype.name = 'haha'; Aaa.prototype.age = 18; var a1 = new Aaa(); console.log(a1.construtor); 2 【构造函数是Aaa】
1 Aaa.prototype = { name = 'haha', age = 18}; var a2 = new Aaa(); console.log(a2.constructor); 【构造函数是Object】
1 例如:var a1 = new Aa(); a1.toString == Object.prototype.toString; 【true】 2 var arr = []; arr.toString == Object.prototype.toString; 【false】