1.CSS和JS在网页中的放置顺序是怎样的?
CSS一般放在head标签,因为CSS加载时可以并发请求(IE6除外),不阻碍其他资源的同时加载。这样对于网速缓慢的用户在浏览网页时能够让内容和样式更为顺畅的显示出来,从而提高用户体验,优化网页性能
JS一般放在body标签的尾部,因为JS加载时是阻塞加载,即JS需要加载完成后才加载其他资源,为了避免这一问题,故将JS放置到尾部能够在不影响页面呈现前提下,实现JS资源的后续下载
2.解释白屏和FOUC
所谓白屏,是指CSS渲染时间过长,而HTML元素的渲染在CSS之后,导致浏览器视窗出现白屏——什么内容也没有,一片空白的现象。
常见于对于IE、chrome等浏览器,若将css放在body标签底部,页面会等css加载完后才显示内容;另一种情况是若使用@import标签引用样式,即便css放在head标签,也可能出现白屏所谓FOUC,全称叫做Flash of Unstyled Content,中文名为无样式内容闪烁,是指浏览器先对HTML元素进行渲染,然后等CSS加载完后重新对页面的样式进行渲染一次导致的页面样式的突然闪现现象
常见于将css内容放在body标签尾部
3.async和defer的作用是什么?有什么区别
js在页面加载时遵循同步加载的原则,就如同HTML在渲染时遵循flow based layout,除非出现float/position/overlfow等改变正常文档流的定位机制。
同理,async和defer都是改变js同步加载的两种方法,可以改变js同步加载导致的网页性能优化问题。
- defer是script标签中处理脚本运行的属性之一,中文称作延时,作用是js在页面加载后才会运行脚本,即同时加载js,延时执行js。
语法规则为:
<script src="demo.js" defer="defer"></script>
- async(HTML5)是script标签中处理脚本运行的另一属性,中文称作异步,作用是脚本会异步加载而不阻塞页面加载,并且js一旦下载完毕就会立即执行。
<script src="demo.js" async="async"></script>
关于二者的加载和执行方式如下图所示:
【注意】无论是defer还是async都仅适用于外部脚本
-
defer和async的比较
相同点:
加载文件时不阻塞页面渲染;
对于inline的script无效;
使用这两个属性的脚本中不能调用document.write方法;
有脚本的onload的事件回调;
允许不定义属性值,仅仅使用属性名;
不同点:
html的版本html4.0中定义了defer;html5.0中定义了async;这将造成由于浏览器版本的不同而对其支持的程度不同;
执行时刻:每一个async属性的脚本都在它下载结束之后立刻执行,同时会在window的load事件之前执行。所以就有可能出现脚本执行顺序被打乱的情况;每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在document的DOMContentLoaded之前执行。
4.简述网页的渲染机制
- 解析文档并构建树:Html解析以构建DOM Tree和Css解析以构建Style Rules Tree
- 构建渲染树Render Tree:此时渲染引擎会将DOM Tree和Style Rules Tree结合在一起形成Render树,它由一些包含有颜色和大小等属性的矩形组成
- 布局Layout:Render树构建好了之后,将会执行布局过程,它将确定每个节点在屏幕上的确切坐标。
-
绘制paint:再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。
5.JavaScript 定义了几种数据类型? 哪些是简单类型?哪些是复杂类型?
六大数据类型:数值型、字符串型、布尔型、对象、数组、函数
简单类型:数值型、字符串型、布尔型
复杂类型:对象、数组、函数
【注】
1.数组和函数算是广义的对象,null也属于对象
2.NaN是一种特殊的数值
6.NaN、undefined、null分别代表什么?
- NaN:表示Not a Number,不是一种独立的数据类型,而是一种特殊数值,它的数据类型依然属于Number,只不过数值计算时不符合计算法则
0/0//NaN
Math.sqrt(-5)//NaN
- null是一个表示"无"的对象,转为数值时为0;
- undefined是一个表示"无"的原始值,转为数值时为NaN。
也就是说:关于null和undefined的使用场景,object初始化时最好使用null,而基本数据类型最好使用undefined ,但是二者在本质上是没有区别的,是JS的一个bug!
7.typeof和instanceof的作用和区别?
-
typeof是返回一个字符串并显示为参数数据类型的运算符,但它无法区分数据类型object究竟是出自狭义的对象object还是数组
示例如下:
typeof 37 === 'number';
typeof "bla" === 'string';
typeof true === 'boolean';
typeof Symbol('foo') === 'symbol';
typeof undefined === 'undefined';
typeof {a:1} === 'object';
typeof [1, 2, 4] === 'object';
typeof function(){} === 'function';
- instanceof运算符可以用来判断某个构造函数的prototype属性所指向的對象是否存在于另外一个要检测对象的原型链上,简单的讲就是判断一个变量是否是某个对象(类)的实例,返回值是布尔类型的。
function C(){}
function D(){}
var a = new C();
var b = new D();
var bool1=a instanceof C
var bool2=a instanceof D
//bool1是C对象的实例
console.log(bool1)
//bool2不是C对象的实例
console.log(bool2)
- typeof 和 instanceof 应用实例
8.代码题
1.完成如下代码判断一个变量是否是数字、字符串、布尔、函数
- 代码录入操作
function isNumber(el){
if (typeof el === "number"){
return true;
} else {
return false;
}
}
function isString(el) {
if (typeof el === "string"){
return true;
} else {
return false;
}
}
function isBoolean(el){
if (typeof el === "boolean"){
return true;
} else {
return false;
}
}
function isFunction(el){
if (typeof el === "function"){
return true;
} else{
return false;
}
}
var a = 3.14,
b = "hello world",
c = false,
d=function D(){};
console.log(isNumber(a));//true
console.log(isString(b));//true
console.log(isBoolean(c));//true
console.log(isFunction(d));//true
console.log(isNumber(b));//false
console.log(isString(d));//false
console.log(isBoolean(a));//false
console.log(isFunction(c));//false
2.以下代码的输出结果是?
console.log(1+1); //2
console.log("2"+"4"); //24
console.log(2+"4"); //24
console.log(+new Date()); //1465811462860
console.log(+"4"); //4
3.以下代码的输出结果是?
var a = 1;
a+++a;
//a++ -> a+1=2 ->2+a = 3,即a+++a返回值为3
typeof a+2;
/typeof a -> "number" -> "number" + 2 -> "number2",即"number2"
4.遍历数组,把数组里的打印数组每一项的平方
//for 循环方法
var arr = [3,4,5];
for (i=0;i<arr.length;i++){
array=Math.pow(arr[i],2);
console.log(array);
}
//while 循环方法
var i = 0;
while (i < arr.length){
array=Math.pow(arr[i],2);
console.log(array);
i++;
}
//do while 循环方法
do {
array=Math.pow(arr[i],2);
console.log(array);
i++;
}while(i < arr.length)
5.遍历 JSON, 打印里面的值
var obj = {
name: 'hunger',
sex: 'male',
age: 28
};
var key;
for (key in obj){
console.log(key + ":" + obj[key])
}
6.下面代码的输出是? 为什么
console.log(a);
var a = 1;
console.log(a);
console.log(b);
//相当于
var a;
console.log(a);//undefined
a=1;
console.log(a)//1
console.log(b)//b is not defined
由于js存在变量提升机制,使得a的声明提升至最前面,此时由于a只声明未赋值,所以数据类型为undefined;
到了a=1时,输出1;
最后,由于b为声明,所以控制台报错。
参考资料
网站前端性能优化之javascript和css
js和css放置位置
引用JavaScript文件时的两个属性defer和async
HTML 5 <script> async 属性
HTML 5 <script> defer 属性
instanceof和typeof运算符的区别详解