嗯,是的。我最近正在努力尝试做出一些转变,当然不是生活习惯,而是我现在和未来赖以生存的编程语言以及使用工具上。而这都是出于一个目的 —— 提升自己的编程能力、短期内将焦点关注在公司需要的技术上。我开始:
- 进入php的世界了。
- 不用emeditor写代码了,而转为Coda,进而下一步转为vim。vim熟了很牛逼,而刚刚接触会很难用的。但就像导师说的,早晚都会成为初学者,何不早点儿开始呢?
- 多用命令行。一来适应项目需要,如svn和终端操作;二来可以装逼。
- 多用各种快捷键,提高效率。
- 改回用mac os了。听说mac里装个win 7会被鄙视的…
自从开始进入公司实习,老实讲,压力还是很大的。作为一个写了一年多前端代码的人,被安排到通用组去写PHP代码,着实感到迷茫和摸不着头脑。况且周围充满着高手和大牛,自己就像个愣头愣脑的小白菜。但其实这是很好的一个小组,包括组内的同事和眼下的项目。关键是自己怎么看待这样的转变。小宇宙还在酝酿,我要做的就是 —— 改变自己,适应需求,然后将其转化为对自己技术全面的收益。
真的偶尔会无所适从。所以写一篇文章,自己鼓励自己一下吧。 :)
To be strong , To be passionated..
基本原理
前面文章提到过,在js中变量包括5中基本类型以及一个复杂数据类型Object,当然常用的函数和数组都是对象。对于基本类型和复杂类型,对应着两种不同的存储方式–栈存储和堆存储。为什么要实现两种存储方式的理由很简单,就是基本类型一旦初始化则内存大小固定,访问变量就是访问变量的内存上实际的数据,称之为按值访问。而对象类型说不定什么时候就会增加自身的大小,内存大小不固定。比如动态添加对象的属性、动态增加数组的大小等等都会使变量大小增加,无法在栈中维护。所以js就把对象类型的变量放到堆中,让解释器为其按需分配内存,而通过对象的引用指针对其进行访问,因为对象在堆中的内存地址大小是固定的,因此可以将内存地址保存在栈内存的引用中。这种方式称之为按引用访问。 嗯,理解这一点很重要,在以后的编程中可以避免很多问题。 我们来看下如下的代码:
var a = 'I am a string.'; //a,b,c的变量中保存的都是实际的值,因为他们是基本类型的变量
var b = 1010;
var c = false;
var d = a; //d中保存着和“a值一样的副本,它们互不影响”
a = 'I am different from d';
alert(d); //输出'I am a string'
以上代码很好理解,就是说按值访问的变量复制“你的就是你的,我的就是我的,咱们都有副本,互不影响。”而对于按引用访问则稍有不同:
var e = {
name : 'I am an object',
setName : function(name){
this.name = name;
}
};
var f = e; //赋值操作,实际上的结果是e,f都是指向那个对象的引用指针
f.setName('I am different from e,I am object f.');
alert(e.name); //对f进行操作,e的值也改变了!
对于引用类型的赋值,说白了,就是把那个对象的指针复制了过去,两个指针指向的都是同一个实体对象,不存在副本,原本的对象还是只有一个!好。以上就是基本类型和引用类型的最大最根本的差别!我用一张图来形象的表示下: 
*栈内存中存放基本类型变量,以及对象的指针;堆中存放对象实体 (more…)
这几天在闭门深入研究原生JavaScript与DOM,反复阅读了几本书之后,遇到了几个难点与困惑之处,比如this、闭包、原型继承等语言特性。今天来说下this。
this是js中最令人迷惑的地方之一了,初学者很容易把this的值和作用域联系到一起,其实this的值只与调用时函数所处的执行环境(execution context)相关,与函数作用域没有一点关系。常常有以下几种情景或者函数调用模式可以判别this所指的值:
1.函数作为对象的方法
当函数作为对象的方法时,this所指的即为包含该方法的那个对象。(函数方法顶层作用域中的this,不是嵌套函数nested function的情况)。这种情况比较常见,比如下面的代码:定义了一个rectangle对象,这个对象有两个属性和一个面积方法,调用时在方法体内的this被绑定到该对象rectangle。
var rectangle = {
width : 20,
height : 10,
area : function(){
return this.width * this.height; //当调用area()方法时,this的值为该对象,也就是rectangle
} //返回值语句可以替换为 return rectangle.width * rectangle.height;
};
rectangle.area() //输出200
如果我想要给rectangle对象再添加一个计算周长的方法,并且在方法内部又定义了一个用于计算的函数(嵌套函数),那么这个函数中的this将是怎么样的呢?倘若我在此calculator函数中直接使用this,那么这个嵌套函数(nested function)的this值将被绑定到全局对象window!
Douglas Crockford对这种完全相同的情况有一番解释,“当函数以此模式调用时,this被绑定到全局对象!这是语言设计上的一个错误,当内部函数被调用时,this应该仍然绑定到外部函数的this变量。这个设计错误的后果是方法不能利用内部函数来帮助它工作,因为内部函数被绑定了错误的值,所以不能共享该方法对对象的访问权。”嗯,牛人可以直指语言的设计错误,我们只要寻求解决方案就可以啦:给该方法定义一个变量并给它赋值为this,那么内部函数就可以通过那个变量访问到外围函数的this,也就是rectangle对象。这样,that就会携带者rectangle对象的引用而传递到了嵌套的函数中去了。
rectangle.circumference = function(){ //给对象增加一个计算周长的方法
var that = this;
var calculator = function(){ //方法中的嵌套函数this将会绑定为window,用变量that传递this值为解决方案
return 2*that.width + 2*that.height;
};
var value = calculator();
return value;
}
rectangle.circumference(); //输出60
2.构造函数情况
当this出现在构造函数中,this的值即为刚new好的那个对象。如下面代码所示,Rectangle为长方形的函数构造器,初始化对象的输入为宽和高,那么通过this关键字,这两个值将会分别被赋值到新创建的对象的属性中去。对于构造函数this值绑定的实质是:“如果在一个函数前面带上new来调用,那么将创建一个隐藏链接到该函数的prototype成员的新对象,同时this将会被绑定到那个新对象上去。”
function Rectangle(width, height){ //Rectancle函数构造器
this.width = width;
this.height = height;
};
Rectangle.prototype.area = function(){
return this.width * this.height;
};
var someR1 = new Rectangle(20,10);
var someR2 = new Rectangle(40,20);
someR1.area(); //200
someR2.area(); //800
(more…)
弱类型
关于数据类型,在熟悉的传统编程语言如C/C++、Java中,我们知道变量都是强类型的。也就是说声明的时候int呀、String呀、Array呀都是预先定义的变量类型,声明变量时必须定义某种类型,不这样做编译器将会报错。但在JavaScript这种松散类型语言的世界里,则完全不同。取而代之的是使用 var 关键字声明一个变量,而不管里面存储的是什么类型的值。换言之,每个变量所保存的仅仅是一个占位符而已。如:
var something1; //undefined
var something2 = 'hello' //声明同时赋予变量一个字符串值
somehing3 = 100; //全局变量
看似这种改变为初始化类型方便了许多,但是,在后续的代码中更要注意陷阱以及类型的判断。而且,JS变量也是有其自己具体的类型的。
数据类型
JavaScript共有5中基本数据类型:Undefined、Null、Boolean、Number和String。以及一个复杂的数据类型Object。 这里有几点需要说明:
1.当声明一个变量但在没有给它赋值初始化之前,变量中保存的值就为undefined,如上面 something1。然而,令人困惑的是,如果没有声明something4,当使用typeof检查其类型的时候也会显示undefined。这会导致我们不清楚是该变量是未赋值还是根本不存在的。推荐在声明变量时养成显示赋值的习惯,这样当项目中typeof检测到undefined的时候,就说明这个变量是未定义的了。
2.当声明时候给变量值加上引号,无论里面是字母还是数字,其类型都为string。数字或者布尔值可以不加引号即为其类型,否则得使用类型转换将string转换为number或者boolean。
3.Object本质上就是由一组无须的名值对组成的(非要有序的话可以是数组,数组是Object的一个子集)。
(more…)
嗯,就在上个月的下旬,经过三次紧张的电话面试,终于拿下百度的实习生offer--我所喜爱的web前端研发部门。在此过程中有以下几点我最为印象深刻:
- 效率很高。从接到电话通知让我准备面试到拿到offer的过程仅仅为6天的时间,而这期间还隔了个周末。
- 对应聘者很尊重。每次电话面试前都会提前一天询问并确定我第二天是否方便进行面试,这让我感到很舒服并且有时间从心理上和技术上进行一些准备。
- 技术问题跨度很广。尤其是二面,问了包括HTML、CSS、JS、bug调试、性能优化、语意化、用户体验、交互设计、Struts、Hibernate、数据库、涉及模式、团队协作…等等等等前端后台我学过的几乎都给为了各遍。导致我答题时候思维一直跳跳跳几乎死机…
- 工程师人很好。拿到offer后,我电话咨询了下从现在到入职这期间需要提高哪些方面,当时工程师正在加班然后第二天早上就针对我面试的情况耐心的发了一封建议邮件,并用短信确定我已收到。嗯,很友好。
以下我来详细介绍下面试的过程:
一面
预约的是下午2点电面,然后2点半左右电话响起…声音很和蔼,是个很客气的工程师。打过招呼后,他笑着说那我们聊一聊吧,气氛很轻松。电话那边他是对着我的实习生demo来看的,那上面有之前完成的作品列表,所以我很熟悉很流畅的一个个的讲解了遍。他笑笑说,嗯,项目经验还蛮多的。接下来就问了具体的CSS技术细节,当时的问题我记不太请了,印象深刻的就是有关于项目中遇到的bug,我举了IE6 double margin,盒模型解析错误这种众所周知的问题。接下来谈了谈关于网站性能优化方面,刚巧之前的post里我专门做了思维导图进行了总结,印象深刻,所以这部分我认为答的很有条理很全面。再接下来问得就是js相关,我说项目中比较熟悉基于jQuery库来完成动态交互,他表示原生js是很重要的然后问了我几个重要的基本概念,比如绑定事件的方式、闭包的概念,客户端存储等。虽然没有原生js的项目经历,但毕竟是搞前端的,这些基本问题还算支支吾吾答了上来。最后,他表示我CSS基础很好,一面结束。 (more…)
题目是这样的:

好,给出我的答案:
纯CSS方案
<ul id="nav">
<li>第一层li第一个元素
<ul>
<li>第二层li元素</li>
<li>第二层li元素</li>
</ul>
</li>
<li>第一层li第二个元素
<ul>
<li>第二层li元素</li>
</ul>
</li>
<li>第一层li第三个元素
<ul>
<li>第二层li元素</li>
<li>第二层li元素</li>
<li>第二层li元素</li>
</ul>
</li>
</ul>
CSS代码:
#nav > li {float:left;list-style:none;margin:0 20px;}
#nav ul {display:none;}
#nav > li:hover ul {display:block;background:#ececec;}
纯CSS方案:查看演示Demo
(more…)
前一段时间在做我的实习生作品系列,到后期的时候有关性能的几个问题凸显了出来。比如图片加载太慢,切换主题时候短暂白屏,以及先显示无样式的文档再加载CSS布局等等性能糟糕的情况。所以随后,针对web前端优化我系统的学习然后总结了下,于本文中写下相关笔记。
首先,在切入主题之前,我想与大家分享的是一个非常经典的性能黄金法则:
“只有10%~20%的最终用户响应时间花在了下载HTML文档上。其余的80%~90%时间花在了下载页面中的所有组件上。”
再来看一下我博客主页上空缓存条件下的HTTP流量显示:

每一个横条都是一次http请求。可以看到,解析生成并下载html文档的时间为811ms+33ms=844ms(第一个蓝色横条),也就是占总时间5.88s的15%不到,其余大部分时间都花在了加载诸如css/js文件,图像等其他组件上了。这说明了什么?这说明web服务器解析php文档并从wordpress后台数据库调取文章、侧边等信息生成html文档的时间确实只占10%~20%。由此可见,后端的响应时间是很少的,大部分的时间都花在了前端组件上。
优化前端所带来的收益与付出的比值远大于优化后台。所以优化前端是很值得的。
由此切入主题 —- 针对前端组件入手,提高响应速度。具体来说,提高前端的性能包括以下三个方面:1.减少http请求次数。2.减小一个http请求所用的时间(也就是减小所请求服务器端组件的大小)。3.改变组件的加载次序以此改变页面的呈现方式(关于优化javascript和css代码以提高执行效率属于高阶技巧,暂不讨论)。对每一方面都有具体的优化方法,我用mindmap图表示出来:

在这里,对于我们的个人站点和项目中最常用和最易提升性能的方法,逐个讨论一下:
(more…)
浮动作为CSS的基石地位无比重要,相信web前端开发人员已经是在熟练不过的了。与之伴随而来的,必然就是清除浮动技术。不同的web发展时期,不同的项目,不同的开发者,他们对于清除浮动的理解以及使用何种技术是不尽相同的。这里简单的总结下能想到的关于清除浮动的方法。
1.直接使用 clear
这是CSS文档中叙述的”官方”清除方法,一般都是这么使用。包括:clear:both , clear:left , clear:right。在实际项目中,经常是让sidebar及content浮动左右,然后在footer中进行一次性清除,代码如下:
*HTML
<section id="content">
<article>...</article>
<article>...</article>
</section>
<aside id="sidebar">..</aside>
<footer>..</footer>
*CSS
#content{
width:60%;
float:right;
}
#sidebar{
width:30%;
float:left;
}
footer{
width:100%
clear:both;
}
(more…)
最近试图用HTML5+CSS3完成一个将设计稿到转换为web界面项目,所以先从结构入手,深入研究了两天HTML5的改进以及新特性,下面谈下我对HTML5的初步印象。
第一 ,< !DOCTYPE html >
最直观的印象莫过于新版本的 DTD 类型声明了,简洁明了,省去了 XHTML1.0 的后面一坨东西,很好记,以后可以不需要 XHTML 的模板而可以直接上手。这种改变 W3school 的解释是,HTML 4.01 中的 doctype 需要对 DTD 进行引用,因为 HTML 4.01 基于 SGML。而 HTML 5 不基于 SGML,因此不需要对 DTD 进行引用,但是需要 doctype 来规范浏览器的行为(让浏览器按照它们应该的方式来运行)。
第二 ,新增了很多也是最让人熟知的,更加富于语义化和结构化的标签。
如 header,nav,section,article,aside,footer 等,作用如其英文本意,这些标签的意义在于方便划分和组织逻辑结构。当 HTML5 广泛推广使用的时候, div 这个无语意的标签的使用率也应该会直线下降,下降到应该用到它的位置。哪位大师说的来着,“div的滥用,无异于无语意的table布局,只是一种更高一级的table应用。”HTML5的出现会使div的使用频率下降很多,标签也会更具语义化。而div再次出现的场合,就该为 “ 在没有更好或者更合适的元素的时候 (Divs should be utilized when there’s no better element for the job)” 。
为方便在 XHTML div布局 与 HTML5 的新元素布局之间进行的比较,我编写了两个demo,您可以查看源代码(html5 , xhtml)或者右键下载该文档。因为没有顾及IE家族对HTML5的支持,如过您用IE打开的话,页面会一团糟。
*html5

*XHTML

第三 ,< hgroup >,< figure >标签
(more…)
混乱的状态
前一段时间,整个人基本处于混沌状态。各种事情蜂拥而至,比如自然辩证法考试、兼职公司要赶项目、各种课程作业和点名得上课,睡眠也是凌晨4点多到第二天中午…就打乱了我原本设想的学习计划。人一忙,就顾不上原来计划好要做的以及技术兴趣方面的事情了,没有更新博客、也没有仔细认真的研究几本书,去图书馆借了不少,都是兴致来了随意的看看,一点儿也不系统。不喜欢这种状态,效率低,目的性不强,也没有一种完成任务的喜悦和满足感,还特累。有必要在这里反思一下。
对我来说,尤其的一点就是:我不善于规划和定制,即使设定了任务,其权重也常常会无意识的默认设置为很低,计划经常被一些无关紧要突然的事儿所替代。这就比如自然辩证法考试来了,这一周我就乱了,尽背书去了。优点就是对学习还算的过程还算比较快乐,最重要的是我喜爱前端开发,对技术富有热情。
分析原因然后找出解决途径
(more…)