1. typeof 产生哪些类型值?
undefined,number,string,boolean,function,object
typeof(null) 值为 object
2. JavaScript 数据类型
基本数据类型:Number,String,Boolean,Undefined,Null
复杂数据类型:Object,Function,Array,RegExp,Date,Error
全局数据类型:Math
var a = 5 +"5";
console.log(a); // 55
var b = "23"<"3";
console.log(b); // true 这里比较的是字符串的字符编码值
var c = true && 2;
console.log(c); // 2
3.作用域
作用域是指变量的作用范围
作用域最大的作用就是隔离变量,不同作用域下的变量名不会产生冲突。
例如:
function fn(){
var a = 100 ;
var b = 200;
return function bar(){
var a = 200;
var b = 400;
console.log(a+b);
}
}
var fn1 = fn();
fn1(); // 600
作用域中变量的值是在执行过程中产生确定的,而作用域是在函数创建的时候确定。
“自由变量”:在A作用域中使用变量x,但是没有在A作用域中声明,对于A作用域来说,x属于自由变量。
对自由变量的取值,要到创建这个变量的函数的作用域中取值。
例子:
function fn(){
var max = 10;
return function bar(x){
if(x > max){
console.log(x)
}
}
}
var f1 = fn();
var max = 100;
f1(15);
这里的最后输出的是 15 ,因为当执行到 var f1 = fn()时,是从fn()函数创建的作用域中取出max值,也就是10,而不是100
4.闭包
由于在JS中,变量的作用域等于函数的作用域,在函数执行完后作用域就会被清理、内存也随之回收,但是闭包是建立在一个函数内部的子函数,由于可以访问上级作用域的原因,即使上级函数执行完后,作用域也不会销毁,这时的子函数–闭包,便拥有访问上级作用域的变量的权限。
5.原型链的概念
原型链是作为继承的主要方式。
每个构造函数都有一个原型对象(prototype)
原型对象里面有一个指向构造函数的指针(constructor)
每个实例都包含一个指向原型对象的内部指针(proto)
原型链的作用在于当读取对象的某个属性时,JS引擎会先寻找对象本身的属性,然后去它的原型上找,原型上找不到就回去原型的原型上找,直到Object.prototype 还是找不到,则返回undefined。
补一张原型分析图:
6. call和apply的区别?
call 和 apply 都是用来改变函数内部this的指向,他们2个第一个参数都是一样的,表示调用该函数的对象,第2个参数,apply是数组。
还有一个 bind 函数: var bar = fn.bind(obj); 那么 fn中的this指向obj对象,bind函数返回新的函数,这个函数的this指针指向obj对象
之前在知乎上看到一段对 call 和 apply 用法总结 形容的相当好:
猫吃鱼,狗吃肉,奥特曼打小怪兽
有天狗想吃鱼了
猫.吃鱼.call(狗,鱼)
狗就吃到鱼了
猫想打小怪兽了
奥特曼.打小怪兽.call(猫,小怪兽)
7.变量提升
var a = 10;
function fn(){
console.log(a); // undefined
var a = 5;
console.log(a); // 5
}
fn();
产生这样结果的原因是Js 解析器会率先读取函数声明,并在执行任何代码前可用;函数表达式则不可以。
8.JavaScript事件模型
原始事件模型,捕获型事件模型,冒泡事件模型
原始事件:ele.onclick = function()
冒泡事件:指事件从事件的发生地(目标元素),一直向上传递,直到document
捕获型则与冒泡相反
IE只支持事件冒泡,浏览器兼容写法见 跨浏览器事件对象
9.内存机制和内存泄漏
基本类型的值在内存中占据固定大小的空间,因为被保存在栈内存中
引用类型的值是对象,保存在堆内存中
内存泄漏是指浏览器不能正常回收内存的现象
10.垃圾回收
原理:找出那些不再继续使用的变量,然后释放其占用的内存
方法1:引用计数
var a = {}; //对象{}引用计数为 1
b = a; //对象{}引用计数为 2
a = null; //对象{}引用计数为 1
方法2:标记清除
11.浏览器JS解析引擎的队列
console.log(1);
setTimeout(function(){
console.log(2)
},0);
console.log(3)
//结果为 1 3 2
首先执行第一条语句,然后将setTimeout 的回调函数放到 异步队列,在执行第三条语句,这样同步队列没有语句,再执行异步队列的回调函数。
12.重构和回流
重构:浏览器的重构指的是改变每个元素外观时所触发的浏览器行为,比如颜色,背景等样式发生了改变而进行的重新构造新外观的过程。重构不会引发页面的重新布局,不一定伴随着回流。
回流:回流指的是浏览器为了重新渲染页面的需要而进行的重新计算元素的几何大小和位置的,他的开销是非常大的,回流可以理解为渲染树需要重新进行计算,一般最好触发元素的重构,避免元素的回流;比如通过通过添加类来添加css样式,而不是直接在DOM上设置,当需要操作某一块元素时候,最好使其脱离文档流,这样就不会引起回流了,比如设置position:absolute或者fixed,或者display:none,等操作结束后在显示。
13.Ajax
原理:通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。
XMLHttpRequest() 属性:
onreadystatechange 每次状态改变所触发事件的事件处理程序
responseText 从服务器进程返回数据的字符串形式
status 从服务器返回的数字代码
readyState 对象状态值:
0(未初始化) 对象已建立,未调用open方法
1(初始化) 对象已建立,未调用send方法
2(发送数据)send方法已调用,但是当前的状态以http头未知
3(数据传送中)
4(完成)
原生写法:
function loadXml(){
var xml;
if(window.XMLHttpRequest){
xml = new XMLHttpRequest();
}else{
//code for IE6,IE5
xml = new ActiveXObject('Microsoft.XMLHTTP');
}
xml.onreadystatechange = function(){
if(xml.readyState == 4 && xml.status == 200){
document.getElementById('box').innerHTML = xml.responseText;
}
}
xml.open('GET','index.txt',true);
xml.send();
}
14.数组方法
栈方法: push() pop()
var color = ['red'];
color.push('green','yellow'); //['red','green','yellow']
console.log(color);
var item = color.pop(); //yellow
console.log(color); //['red','green']
队列方法:unshift() shift()
var color = ['red'];
color.unshift('green','yellow');
console.log(color); //['green','yellow','red']
color.shift('green');
console.log(color); //['yellow','red']
操作方法:slice() splice()
// slice 不会改变原数组
var color = ['red','green','yellow','coral'];
var color1 = color.slice(1);
console.log(color1); //['green','yellow','coral']
var color2 = color.slice(1,3);
console.log(color2); //['green','yellow']
//splice()会改变原数组
var colors = ['red','green','yellow'];
var color2 = colors.splice(0,1);
console.log(color2); // ['red']
console.log(colors); //['green','yellow']
var color3 = colors.splice(1,0,'coral','black');
console.log(color3); //返回空数组
console.log(colors); //['green','coral','black','yellow']
var color4 = colors.splice(1,1,'white','purple');
console.log(color4); //['coral']
console.log(colors); //['green','white','purple','black','yellow']
迭代方法
filter():返回该函数会返回true的项组成的数组
var items = [2,3,4,5,6,7,8];
var filterResults = items.filter(function(item,index,array) {
return item>4;
});
console.log(filterResults); //[5,6,7,8]
map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
var items = [2,3,4,5,6,7,8];
var filterResults = items.map(function(item,index,array) {
return item * 2;
});
console.log(filterResults); //[4,6,8,10,12,14,16]
15.优雅降级和渐进加强
优雅降级指的是一开始就构建功能完好的网站,然后在慢慢兼容低版本的浏览器,使得各个浏览器之间的差异不要太大。
渐进加强是指基本功能得到满足的情况下,对支持新特性的浏览器使用新特性,带给用户更好的体验
16.Http
http请求的过程:
浏览器首先向服务器发送http请求
请求包括:GET仅请求资源,POST会附带用户数据
服务器向浏览器返回http响应
响应代码:200表示成功,3xx表示重定向,4xx表示客户端发送的请求有错误,5xx表示服务端处理发生错误
响应类型:由 Content-Type 决定
17.严格模式
- 严格模式中禁止使用with语句
- 在严格模式中,调用的函数(非方法)中的 this 值是 undefined(非严格模式中,调用的函数中的this值总是全局对象)
- 严格模式中,所有变量都要先声明
18.前端优化
- 使用 CDN 减少服务器负担
- 预加载 CSS JS 文件
- 懒加载图片
- 压缩 CSS JS文件,减小文件体积