聊聊JS那些事--严格模式

什么是严格模式?

严格模式 是 ECMAScript 5 中引入的一种将更好的错误检查引入代码中的方法, 现在已经被大多浏览器实现. 顾名思义,这种模式使得Javascript在更严格的条件下运行.

因此, 在严格模式下, 我们的一些不严谨的写法将会导致程序抛出错误. 例如:

1
2
3
function fn(param) {
var arguments = []; // 在严格模式下该行将会抛出错误: error: redefinition of arguments
}

在上面的代码中, 由于 arguments 在 js 中是一个特殊对象, 在严格模式下是不允许被重新定义的. 但是没有实现严格模式检查的环境中会接受这段代码.

为什么会出现严格模式?

总所周知, 从 ECMAscript 从1997年正式成为国际标准以来, 已经发布了6个版本. 除此之外, 还存在一些 Javascript 实现支持非标准特性, 而其他的 Javascript 实现却并不支持这些特性的情况. 由于 Javascript 的实现多样化, 我们很难确定哪些特性在哪些平台上是支持的, 再加上 Web 浏览器的复杂性, 并且它并不能让开发者指定某一个特定的 Javascript 版本来执行我们的程序. 因此我们需要精心的编写程序, 以确保在所有的平台上都能够正常运行.

因此在 ES5 中引入了一种版本控制的考量: 严格模式. 此特性允许开发者选择在受限制的 Javascript 版本中禁止使用一些 Javascript 语言中问题较多或是易于出错的特性.

由于其语法强大的向后兼容特性, 所以即使在没有实现严格模式检查的环境中, 你的严格代码仍然可以正常执行.

Read More

使用canvas绘制时钟

准备工作

在HTML中指定一个区域放置时钟:

1
<div id="clock" style="position: relative;"></div>

时钟的一些外观设定:

1
2
3
4
5
6
7
8
9
var width = 260; // 桌布宽度
var height= 260; // 桌布高度
var dot = {
x : width / 2,
y : height / 2,
radius : 6
}; // 圆点位置、半径
var radius = 120; // 圆半径
var borderWidth = 6; // 圆边框宽度

创建<canvas>元素:

1
2
3
4
5
6
7
8
9
10
11
12
var clock = document.getElementById('clock');
var clockBg = document.createElement('canvas');
var clockPointers = document.createElement('canvas');
clockPointers.width = clockBg.width = width;
clockPointers.height = clockBg.height = height;
clockPointers.style.position = 'absolute';
clockPointers.style.left = 0;
clockPointers.style.right = 0;
clock.appendChild(clockBg);
clock.appendChild(clockPointers);

这里要创建两个<canvas>元素,目的在于把时钟的圆盘跟指针分离开。这是因为指针要根据当前时间擦除重绘,如果放置在一个<canvas>中,擦除的时候就会把圆盘也给擦掉了。

Read More

ECMAScript 6中的面向对象

ECMAScript 6(下面简称ES6)增强了对面向对象的支持,引入了class关键字,并且为类的创建、继承提供了简洁清晰的语法。

类声明与类表达式

毋庸置疑,class关键字就是用来定义类的。

定义类的常用方式是类声明,语法如下:

1
2
3
4
5
6
7
8
9
10
11
class ClassName {
// 构造函数
constructor() {
// ...
}
// 方法
method() {
// ...
}
}

而另一种方式则是类表达式,语法如下:

1
2
3
4
5
6
7
8
9
10
11
var ClassName = class {
// 构造函数
constructor() {
// ...
}
// 方法
method() {
// ...
}
};

Read More

前端开发书籍推荐目录

前端大牛关于前端开发方面推荐的书籍,我也看过那么几本,有一些还没有看,先收藏在这里:

以下是正文部分。

1、Head First HTML与CSS

这本书最大的优点就是除了基础还是基础,非常适合完全不知道前端开发是什么的门外汉作为第一本入门书籍来学习, 整本书采用插画和故事场景的形式叙述,和那些枯燥、深奥的HTML书籍完全不同,秉持了 Head First 系列一贯通俗易懂的风格。你看这本书的时候会发现就像是在看漫画书一样轻松。是我看过对初学者最友好的书,没有之一。

2、CSS 权威指南

在看了第一本书后,想必你已经对 HTML 和 CSS 的基础知识有了一定的了解,甚至你已经能够做出一些简单的网站了。但是你可能只是知道一些常见的 CSS 属性,毕竟上一本书只是讲解一些基础知识。所以如果你想要全面的、深入的了解 CSS ,那么权威指南系列是你的不二选择。

这是一本非常经典的 CSS 参考书,它的经典之处在于,它用普通人类可以理解的语言系统、全面地讲解了 CSS 规范。这本书会告诉你,CSS 是什么、CSS 有什么、CSS 可以做什么。

这本书就像是 CSS 里面的圣经一样,以神一般的地位存在。当然了,你不要被它的厚度给吓到,其实你在看这本书的时候完全不需要非要每一页都非常详细的看一遍,你只需要粗略的翻一下,了解一下内容,然后大部分情况下把它当做字典来使用。用一个知识点学一个知识点就好了。

3、精通 CSS

这同样是一本非常经典的 CSS 图书,它侧重于实践,告诉你如何正确地使用 CSS。

这本书将最有用的 CSS 技术汇总在一起,还总结了 CSS 设计中的极具实践,讨论了解决各种实际问题的技术,填补了一直以来 CSS 图书的空白。

Read More

封装你的Gulp代码

近年来,前端工程化深入人心,而工程化中必不可少的环节就是构建。所谓构建就是基于既定的流程对项目中的文件进行处理,从而得到最终用于发布的文件。而Gulp正是目前最流行的前端构建工具之一。

Gulp的使用

以下是使用Gulp进行构建的例子,也是本文的示例项目。文件结构为:
– /Users/me/project/project-a
– src/
– dist/
– package.json
– gulpfile.js

其中「src」为源代码目录,「dist」为发布代码目录。「gulpfile.js」的代码为:

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
var gulp = require('gulp'),
gulpCleanCSS = require('gulp-clean-css'),
gulpUglify = require('gulp-uglify'),
gulpMD5 = require('gulp-md5-plus');
// 把.html文件直接copy到发布目录
gulp.task('copy-html', function() {
return gulp.src('./src/*.html')
.pipe( gulp.dest('./dist') );
});
gulp.task('compress-css', ['copy-html'], function() {
return gulp.src('./src/*.css')
// 压缩CSS代码
.pipe( gulpCleanCSS() )
// 文件名增加MD5,并替换.html文件中的引用地址
.pipe( gulpMD5(10, './dist/*.html') )
// 构建到发布目录
.pipe( gulp.dest('./dist') );
});
gulp.task('compress-js', ['copy-html'], function() {
return gulp.src('./src/*.js')
// 压缩JS代码
.pipe( gulpUglify() )
// 文件名增加MD5,并替换.html文件中的引用地址
.pipe( gulpMD5(10, './dist/*.html') )
// 构建到发布目录
.pipe( gulp.dest('./dist') );
});
gulp.task('default', ['compress-css', 'compress-js']);

要正常执行这段代码,还要进行部署。
第一步,全局安装Gulp:

1
npm install gulp -g

Read More

setTimeout/setInterval的最大延时值

先来看这样一段代码:

1
2
3
4
5
6
7
8
9
function update() {
loadData().then(function(data) {
$('#content').html(data.content);
var delay = data.nextUpdateTime - new Date();
if (delay > 0) {
setTimeout(update, delay);
}
});
}

其流程非常简单:通过AJAX加载数据后更新HTML的内容;如果有指定下次更新时间,则通过计时器在该时间点再执行一次整个流程。

要说这段代码有什么隐患的话,那就是data.nextUpdateTime与当前时间的时间差(即delay变量的值)比较小的时候,会导致内容频繁更新。但这是属于正常的业务逻辑,要优化就只能牺牲内容更新的即时性。然而这里我要说的是,当时间差非常大的时候,也会出现同样的问题。

Read More

世界各地程序员共同总结的前端面试题

常规问题

  • 最近你学了什么?
  • 是什么激发你对编程的兴趣?
  • 你最近在挑战什么新技术、你是怎么解决遇到的问题?
  • 当你在构建Web应用程序或网站时,你会考虑什么样的用户界面、安全性、性能、SEO、可维护性、选用的技术?
  • 谈谈你首选的开发环境(系统、编辑器或IDE、浏览器、工具等)
  • 你熟悉什么版本控制系统?
  • 请描述一下你创建一个网页的工作流程?
  • 请描述一下渐进增强和优雅降级的区别?
  • 如何优化一个网站的资源?
  • 传统上,为什么网站资源来自多个域会更好?
  • 浏览器能同时下载某个域的多少资源?
  • 如果你加入了一个项目,他们使用tab键进行格式化,而你使用空格键,你会做什么?
  • 写一个简单的幻灯片
  • 你使用什么工具来测试代码性能?
  • 如果你今年能掌握一门技术,它会是什么?
  • 尽量详细地描述从输入一个网站的URL到页面完成加载的过程。
  • 解释什么是ARIA和screenreaders,和提高网站可读性的办法。
  • 比较一下CSS动画和JavaScript动画优、缺点的

    Read More

CSS--FLex布局介绍

网页布局(layout)是CSS的一个重点应用。

布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。

Read More

滴滴出行前端面试总结

2017年4月6日参加【滴滴出行-杭州-前端技术开发-实习生】现场面试,招聘要求如下:

职位诱惑

  • 15薪 + 定期团建 + 转正15k-20k

岗位职责

  • 负责PC及移动端APP产品的前端代码开发工作,撰写相关技术文档
  • 负责对产品页面性能的优化和维护,持续提升用户体验
  • 负责可视化产品、通用组件的开发

任职要求

  • 本科或以上学历,计算机相关专业,1年以上工作经验
  • 精通各种Web前端技术(HTML5/CSS/Javascript等),熟悉跨浏览器、跨终端的开发
  • 深刻理解Web标准,对前端性能、可访问性、可维护性等相关知识有实际的了解和实践经验
  • 掌握ios/Android等移动平台浏览器的特性,精通各平台浏览器兼容性解决方案,熟练掌握移动端的性能优化
  • 熟悉javascript面向对象机制,能用原生javascript进行DOM编程;至少熟悉一种javascript框架,能够使用框架快速开发
  • 对前端工程化与模块化开发有一定了解,并有实践经验(如RequireJS/SeaJS/ES6等)
  • 有数据可视化实际项目开发经验者优先
  • 有移动端hybird混合模式项目开发经验者优先

技术面试

1.【CSS】如何实现单行文本结尾以省略号显示,多行文本以省略号显示:

单行省略号显示代码:

1
2
3
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;

Read More

聊聊JS那些事--继承

1、小思考

我记得初学js时,最难懂的概念就是js的原型,而且这个概念在笔试面试中常常提到,因此今天我们把这个概念拿出来,好好聊一聊。

在仔细讲解之前,我们先来看一道题,这道题来自JavaScript高级程序设计中原型链那一节:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue());

可以猜一猜最后alert出的结果是什么?

先思考一下再看下面的内容。

Read More