JavaScript原型和原型链
每个对象都会在其内部初始化一个属性,就是prototype,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,就是原型链的概念
闭包
闭包就是能够读取其他函数内部变量的函数。例如js中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解定义在一个函数内部的函数。在本质上,闭包是函数内部和外部连接起来的桥梁。
函数防抖和节流
防抖:只执行最后一个被触发的,清除之前的异步任务,核心在于清零。
function debounce(fn, delay) {
var timer = null;
return function () {
var that = this;
var args = arguments;
clearTimeout(timer);// 清除重新计时
timer = setTimeout(function () {
fn.apply(that, args);
}, delay || 500);
};
}
节流:只在开始执行一次,未执行完成过程中触发的忽略,核心在于开关锁
// 节流
function throttle(fn, delay) {
var timer = null;
return function () {
if (timer) { return false;}
var that = this;
var args = arguments;
fn.apply(that, args);
timer = setTimeout(function () {
clearTimeout(timer);
timer = null;
}, delay || 500);
};
}
this指向问题
普通函数调用 this指向windows;
对象函数调用 this指向这个对象;
构造函数调用 this指向当前实例本身(新创建的对象);
call和apply,bind调用 传入什么指向什么,传入的参数;(call可以传多个参数,apply可以传二个参数,第二个数组,不然报错TypeError) 箭头函数调用 this指向上级作用域的值(当前函数上下文);
new操作符具体干了什么
- 创建一个空对象
- 继承了该函数的原型
- 属性和方法被加入到 this 引用的对象中
- 新创建的对象由 this 所引用,并且最后隐式的返回 this
面向对象编程
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事务在整个解决问题的步骤中的行为。面向对象是以功能来划分问题的,而不是步骤。面向对象使用对象,类,继承,封装等基本概念来进行程序设计。
优点:可读性高,易于使用,易复用,易扩展,由于面向对象有封装、继承、多态的性。可以设计出低耦合的系统,使系统更加灵活、更加易于维护。
缺点:类的调用需要实例化,开销比较大,性能比面向过程低
面向过程编程
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候依次调用就可以了;
优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源,例如Linux
缺点:没有面向对象易于维护、易复用、易扩展
箭头函数与普通函数的区别
普通函数可以改变this指向,this指向调用它的对象,而箭头函数的this指向不能改变,且指向其上下文。
箭头函数不可以当做构造函数,普通函数可以
垃圾回收机制
- 标记清除(mark and sweep)
- 这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”
- 垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了
- 引用计数(reference counting)
- 在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。
- 引用计数的策略是跟踪记录每个值被使用的次数。
- 当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1
- 如果该变量的值变成了另外一个,则这个值得引用次数减1,
- 当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间
深拷贝和浅拷贝
浅拷贝:比如说一个数组,只要我们修改一个拷贝数组,那么原数组也会改变。
深拷贝:则相反,将会给数组创建独立的内存,并将原数组内容一并拷贝进来,2者互不影响。
//深拷贝
JSON.parse(JSON.stringify(object))
进程与线程
进程描述了cpu在运行指令及加载和保存上下文所需要的实际,放在应用上来说就是代表一个程序。
线程是进程中更小的单位,描述了执行指令所需的时间
举例:当你打开一个tab页面其实就是创建一个进程,一个进程可以有多个线程,比如渲染线程、js引擎线程、http请求线程。当你发起一个请求的时候其实就是创建了一个线程,当请求结束后,该线程可能就被销毁。
什么是event loop (事件循环/事件轮询)
js是单线程运行的
一步就要基于回调来实现
event loop就是异步实现的原理
event loop过程
整个过程包含:1、call stack(调用栈)2、webApis(浏览器api)3、callback queue(回调函数队列)4、event loop(事件轮询)