说到js和css的位置,大家应该都知道js放在下面,css放在上面。但是,如果你的项目只需要兼容ie10+或者只是在移动端访问,那么可以使用HTML5的新属性async,将脚本文件放在内兼容老旧浏览器(IE9-)时:脚本引用写在 body 结束标签之前,并带上 async 属性。这虽然在老旧浏览器中不会异步加载脚本,但它只阻塞了 body 结束标签之前的 DOM 解析,这就大大降低了其阻塞影响。而在现代浏览器中:脚本将在 DOM 解析器发现 body 尾部的 script 标签才进行加载,此时加载属于异步加载,不会阻塞 CSSOM(但其执行仍发生在 CSSOM 之后)。综上所述,所有浏览器中推荐:
See the square next to me? css 代码: .text-box > .square { display: inline-block; width: 1rem; height: 1rem; background-color: red; }
推荐
html 代码: See the square next to me? css 代码: /* We use a :before pseudo element to solve the design problem of placing a colored square in front of the text content */ .text-box:before { content: ""; display: inline-block; width: 1rem; height: 1rem; background-color: red; }
图片和 SVG 图形能被引入到 HTML 中的唯一理由是它们呈现出了与内容相关的一些信息。
不推荐
html 代码: See the square next to me?
推荐
html 代码: See the square next to me? css 代码: /* We use a :before pseudo element with a background image to solve the problem */ .text-box:before { content: ""; display: inline-block; width: 1rem; height: 1rem; background: url(square.svg) no-repeat; background-size: 100%; }
js规范
避免全局命名空间污染
防止全局命名空间被污染,我们通常的做法是将代码包裹成一个 IIFE(Immediately-Invoked Function Expression),创建独立隔绝的定义域。也使得内存在执行完后立即释放。
var x = 10, y = 100; // Declaring variables in the global scope is resulting in global scope pollution. All variables declared like this // will be stored in the window object. This is very unclean and needs to be avoided. console.log(window.x + ' ' + window.y);
推荐
// We declare a IIFE and pass parameters into the function that we will use from the global space (function(log, w, undefined){ 'use strict'; var x = 10, y = 100; // Will output 'true true' log((w.x === undefined) + ' ' + (w.y === undefined)); }(window.console.log, window));
推荐的IIFE写法:
(function(){ 'use strict'; // Code goes here }());
(function(log){ 'use strict'; var a = 10; for(var i = 0; i < a; i++) { var b = i * i; log(b); } if(a === 10) { var f = function() { log(a); }; f(); } function x() { log('Mr. X!'); } x(); }(window.console.log));
提升后的js
(function(log){ 'use strict'; // All variables used in the closure will be hoisted to the top of the function var a, i, b, f; // All functions in the closure will be hoisted to the top function x() { log('Mr. X!'); } a = 10; for(i = 0; i < a; i++) { b = i * i; log(b); } if(a === 10) { // Function assignments will only result in hoisted variables but the function body will not be hoisted // Only by using a real function declaration the whole function will be hoisted with its body f = function() { log(a); }; f(); } x(); }(window.console.log));
Array.prototype.valueOf = function() { this[0]++; return this; } var x = [1, 2, 3]; x == 0; console.log(x); // [2, 2, 3]复制代码
===操作符:
要是两个值类型不同,返回false
要是两个值都是number类型,并且数值相同,返回true
要是两个值都是stirng,并且两个值的String内容相同,返回true
要是两个值都是true或者都是false,返回true
要是两个值都是指向相同的Object,Arraya或者function,返回true
要是两个值都是null或者都是undefined,返回true
真假判断
js中以下内容为假:
false
null
undefined
0
'' (空字符串)
NaN
设置默认参数
辑操作符 || 和 && 也可被用来返回布尔值。如果操作对象为非布尔对象,那每个表达式将会被自左向右地做真假判断。基于此操作,最终总有一个表达式被返回回来。这在变量赋值时,是可以用来简化你的代码的。例如:如果x不存在且y不存在,x=1;如果x存在y存在,x = y
if(!x) { if(!y) { x = 1; } else { x = y; } }
等同于:
x = x || y || 1;复制代码
这一小技巧经常用来给方法设定默认的参数。
(function(log){ 'use strict'; function multiply(a, b) { a = a || 1; b = b || 1; log('Result ' + a * b); } multiply(); // Result 1 multiply(10); // Result 10 multiply(3, NaN); // Result 3 multiply(9, 5); // Result 45 }(window.console.log));
只在对象构造器、方法和在设定的闭包中使用 this 关键字。this 的语义在此有些误导。它时而指向全局对象(大多数时),时而指向调用者的定义域(在 eval 中),时而指向 DOM 树中的某一节点(当用事件处理绑定到 HTML 属性上时),时而指向一个新创建的对象(在构造器中),还时而指向其它的一些对象(如果函数被 call() 和 apply() 执行和调用时)。