章节目录:
- JS基础知识(上)——讲解 JS 基础语法相关的面试题,分析原理以及解答方法。这一章节讲解了基础知识的第一部分:变量的类型和计算。以及JS “三座大山” —— 原型、作用域和异步中的第一座大山:原型。
- JS基础知识(中)——讲解 JS 基础语法相关的面试题,分析原理以及解答方法。这一章节讲解了JS “三座大山” —— 原型、作用域。
- JS基础知识(下)——讲解 JS 基础语法相关的面试题,分析原理以及解答方法。这一章节讲解了基础知识的第三部分:JS “三座大山” —— 作用域,闭包及异步。
- JS-Web-API(上)——讲解 JS 在浏览器中具体应用的面试题。包括 DOM 操作,BOM 操作,事件绑定,ajax 和 存储,这些类别的题目。
- JS-Web-API(下)——讲解 JS 在浏览器中具体应用的面试题。包括 DOM 操作,BOM 操作,事件绑定,ajax 和 存储,这些类别的题目。
- 开发环境——讲解在面试过程中,面试官可能会问及的前端开发环境的问题,例如 IDE,Git,模块化,打包工具,上线流程,这些类别的题目。
- 运行环境——讲解 JS 代码在浏览器中运行的相关问题,例如页面加载和渲染,性能优化,安全性,这些类别的题目。
第一部分:JS基础知识(ECMA262标准)
ECMA262标准:
a 变量类型和计算
b 原型和原型链
c 闭包和作用域
d 异步和单线程
e 其他(日期、Math、各种常用API)
1 变量类型和计算
变量类型:值类型、引用类型。
值类型:值之间不相互影响,包括:number、string、布尔。
引用类型:由指针指向对象,包括:对象、数组、函数。
引用类型特点:可以无限的扩展熟悉。
2 typeof运算符
typeof undefined // undefined
typeof 'abc' // string
typeof 123 // number
typeof true // boolean
typeof {} // object
typeof [] // object
typeof null // object
typeof console.log // function
typeof共有五种类型:undefined string number boolean object 。
typeof只能区分值类型:undefined string number boolean 。
null:引用类型,属于object,空的指针。
function:特殊的引用类型。
3 变量计算-强制类型转换
a 字符串拼接
b ==运算符
c if语句
d 逻辑运算
==运算符比较特殊,在表达式null == undefined中,null和undefined都会被转换成false,因此判断结果为true。0和空字符串''同理。
console.log(10 && 0) // 0 //10被转换成了true
console.log('' || 'abc') // 'abc' //''被转换成了false
console.log(!window.abc) // true //window.abc被转换成了false
判断一个变量会被当成true还是false:
var a = 100; console.log(!!a);
在if中会被当成false处理的有:0 NaN '' null undefined false
4 原型和原型链
构造函数:函数名称首字母大写。
function Foo(name,age){
this.name = name;
this.age = age;
//return this; //默认有这一行
}
var f = new Foo('zhangsan',20);
//var f1 = new Foo('lisi',22); //创建多个对象
new一个对象的过程:构造函数相当于一个模板,this.xx = xx; this.xxx = xxx;(赋值)当然也可以不赋值传参。new函数执行时,this变成空对象,然后赋值,之后return this 。
创建一个新对象->this指向这个新对象->执行代码,即对this赋值->返回this。
构造函数扩展:
var a = {} 其实是var a = new Object()的语法糖;
var a = [] 其实是var a = new Array()的语法糖;
function Foo(){...}其实是var Foo = new Function(...)的语法糖;
语法糖的构造函数易读性和性能更好。
使用instanceof判断一个函数是否是一个变量的构造函数。
如何判断一个变量是否为数组:变量 instanceof Array
5 原型规则和示例
5条原型规则:
a 所有的引用类型:数组、对象、函数,都具有对象特性,即可以*扩展属性(除了null以外)。
b 所有的引用类型:数组、对象、函数,都有一个__proto__属性(隐式原型),属性值是一个普通的对象。
c 所有的函数,都有一个prototype属性(显式原型),属性值也是一个普通的对象。
d 所有的引用类型:数组、对象、函数,__proto__属性值指向它的构造函数的prototype属性值。
e 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找。
for(... in ...)循环对象自身的属性:在高级浏览器中,已经在for in中屏蔽了来自原型的属性,但是建议大家加上判断,保证查询的健壮性。
var item;
for(item in f){
if(f.hasOwnProperty(item)){ //hasOwnProperty函数方法返回一个布尔值,指出一个对象是否具有指定名称的原生属性,若有返回true,若无返回false.
console.log(item);
}
}
6 原型链
f.toString() //要去f.__proto__.__proto__中查找。
7 instanseof
用于判断引用类型属于哪个构造函数的方法。
f instanceof Foo的判断逻辑是:f的__proto__,一层一层往上,能否对应到Foo.prototype;再试着判断f instanceof Object(Foo的上一层是Object)。
8 执行上下文
范围:一段<script>或者一个函数。
全局:变量声明,函数声明。 一段script
函数:变量定义,函数声明,this,argument. 函数
注意区分函数声明和函数表达式!
执行上下文会在执行第一行代码前把所有变量的声明和函数的声明都拿出来。
9 this
this在执行的时候才能确认值,定义时无法确认。
this的几种使用场景:
a 作为构造函数执行
b 作为对象属性执行
c 作为普通函数执行 this是window
d call apply bind
10 作用域
没有块级作用域
只有函数和全局作用域
11 作用域链
*变量:当前作用域没有定义的变量
函数的父级作用域指的是函数定义的地方
注意函数和全局中不要混用同一变量!
12 闭包
闭包实际应用中主要用于封装变量,收敛权限。
13 异步和单线程
因为javascript是单线程语言,只能每次执行一件事
何时需要异步?前端使用一笔的场景有哪些?
a 定时任务:setTimeout,setInterval
b 网络请求:ajax请求,动态<img>加载
c 事件绑定
异步和同步的区别:
a 同步会阻塞代码执行,而异步不会
b alert是同步,setTimeout是异步
14 其他题目
日期:
Date.now() //获取当前时间毫秒数
var dt = new date();
dt.getTime() //获取毫秒数
dt.getFullYear() //年
dt.getMonth() //月(0-11)
dt.getDate() //日(0-31)
dt.getHours() //小时(0-23)
dt.getMinutes() //分钟(0-59)
dt.getSeconds() //秒(0-59)
Math:
获取随机数:Math.random() 返回0.xxx,位数不确定
应用:清楚缓存。当持续访问同一链接时,会得不到真实的访问效果,这时在链接后面加一个random,会每次改变,达到清除缓存的效果。
数组API:
forEach //遍历所有元素
every //判断所有元素是否都符合要求条件
some //判断是否有至少一个元素是否符合要求条件,返回true或false
sort //排序
map //对元素重新组装,生成新的数组
filter //过滤符合条件的元素
sort:
var arr = [1,3,5,2,4];
var arr2 = arr.sort(function(a,b){
return a-b; //从大到小排序
//return b-a; //从小到大排序
})
console.log(arr);
console.log(arr2);
此例中返回的arr和arr2都是排序好的数组,sort方法执行后改变了原数组。
map:
var arr = [1,2,3];
var arr2 = arr.map(function(item,index){
return '<b>'+item+'</b>';
})
console.log(arr2); //["<b>1</b>","<b>2</b>","<b>3</b>"]
filter:
var arr = [1,2,3,4];
var arr2 = arr.filter(function(item,index){
if(item>2)
return true;
})
console.log(arr2); //[3,4]
对象API:
var obj = {
x:100,
y:200,
z:300
}
var key
for (key in obj){
if(obj.hasOwnProperty(key)){
console.log(key,obj[key])
}
}
输出结果:
x 100
y 200
z 300