1.原型链
- 在JavaScript中万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在JavaScript中是通过prototype对象指向原型,再通过proto指向Object对象原型为止,这样就形成了一个原型指向的链条,专业术语称之为原型链。
- 在原型上定义的属性和方法,创建出来的实例也会拥有原型上的属性和方法
- 实例上有属性就用实例的属性,实例上没有就去找原型上的属性,原型上没有就去找原型的原型(原型链终极)上的属性
2.this指向
1.方法调用,this指向拥有这个对象的本身
2.函数调用,this指向Windows
3.构造函数,this指向new出来的实例
4.上下文调用,this指向(你要传进去)传入的对象
- 1.this 不能被赋值,但可以被 call/apply 改变
- 2.this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个最近调用它的对象
- 3.return 和 this 只能出现在函数内
3.作用域与预解析
作用域
作用域: 只有方法(函数)才有作用域,是指可访问变量的集合(变量和函数可被访问的范围)----作用域产生于程序源代码中定义变量的区域,在程序编码阶段就确定了。javascript 中分为全局作用域(Global context: window/global )和局部作用域(Local Scope , 又称为函数作用域 Function context)。简单讲作用域就是当前函数的生成环境或者上下文,包含了当前函数内定义的变量以及对外层作用域的引用。
作用域链:是一条变量对象的链,它和执行期上下文(作用域)有关,用于在处理标识符的时候进行变量查询.,函数上下文的作用域链在函数调用的时候创建出来
预解析
- 在当前作用域中,JavaScript代码执行之前,浏览器首先会默认的把所有带var和function声明的变量进行提前的声明或者定义。
- 声明:var num; 告诉浏览器在全局作用域中有一个num变量了,如果一个变量只是声明了,但是没有赋值,默认值是undefined。
定义:num = 12; 定义就是给变量进行赋值。
预解析只发生在当前的作用域下
var声明的变量和function声明的函数在预解析的时候有区别,var声明的变量在预解析的时候只是提前的声明,function声明的函数在预解析的时候会提前声明并且会同时定义。也就是说var声明的变量和function声明的函数的区别是在声明的同时有没同时进行定义。预编译:变量声明声明提升,函数声明整体提升
JS运行三部曲:
1、语法分析
2、预编译
3、解释执行代码
简单总结:变量声明提升,函数声明整体提升
具体:
1、创建一个AO对象(Activation Object)执行期上下文
2、寻找形参和变量声明作为AO对象属性名,值为undefined
3、将实参与形参统一
4、在函数体中寻找函数声明,值为函数体、
4.new关键字
在函数里面创建一个空对象,将函数里的this指向这个新创建的对象(xxx),再返回这个obj对象
1、创建一个空对象
var obj=new Object();
2、设置原型链
obj.proto= Func.prototype;
3、让Functionj中的this指向obj,并执行Function的函数体。
var result =Func.call(obj);
4、判断Func的返回值类型:
如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象。
5.闭包
- 概念: 闭包就是有权访另一个函数作用域中变量的函数
- 产生的原因: 因为函数作用域的问题
- 形式: 比如一个a函数中return一个函数,在return得这个函数中使用a函数中的变量,
- 缺陷:
- 因为变量在被使用所以无法被垃圾回收机制回收
- 变量得不到释放,增加内存使用率,很容易造成内存泄漏
6.pormise
1.回调地狱
function a(functionb(){
c(function d(){
})
})
我们发现上面代码大量使用了回调函数(将一个函数作为参数传递给另个函数)并且有许多 })结尾的符号,使得代码看起来很混乱。
2.三个状态: pending(初始值,等待), fulfilled(resolve)(代表操作成功),rejected(代表操作失败)
3.promise使用:
有两个·参数:(resolve,recject),resolve接受成功的参数,recject接受失败的,解决回调地狱使用链式编程,在then回调中return一个新的promise。当我们的页面渲染需要所有请求数据一起回来是才开始,我们可以使用promise.all方法,这个方法的特性是需要等所有的请求结果回来是才执行回调函数.then(),说到这个还有一个promise.reace方法,它的特性是最先执行完的请求去使用.then()回调函数当然在平时使用我们一般会使用async await,
4.async/await:
将异步请求变为同步代码,同时的async/await无法捕获错误,我们需要使用,try/catch来捕获错误
是一个用同步思维解决异步问题的方案
async用于声明一个函数是异步的。而await从字面意思上是“等待”的意思,就是用于等待异步完成。并且await只能在async函数中使用
通常async、await都是跟随Promise一起使用的
7.跨域
webSockets
websocket是一个实时通讯协议,可以和服务端建立一个通道:服务器可以主动向客户端推送信息,客户端也可以主动向服务端发送信息。
跨域
-
跨域是由浏览器同源政策引起的,是指页面请求的地址,必须与页面url地址处于(域名,端口,协议相同),是为了防止某域名下的接口被其他域名下的网页非法调用
解决跨域:
- 1:jsonp(浏览器只对XHR请求有同源请求限制,而对script标签的src属性,link标签的ref属性,img标签的src属性没有这种限制,利用这个漏洞就可以很好解决跨域问题。jsonp就是利用script标签没有同源政策限制的特点来实现解决跨域问题的)
- 2:代理服务器(因为同源政策限制只存在于浏览器,服务器之间的请求是不受限制的。通过一些方法设置代理,将不同域名转换为相同的,客户端发送请求是,不直接发送到线上的服务器,而是先发送到本地的代理服务器,再把代理服务器当做一个跳板,再将请求发送到线上服务器。同理,服务器的回应也是先通过代理服务器再转向客户端)
- 3:websocket(是一个持久化的实时通信协议,客户端和服务端建立了一个通道)
8.Ajax
异步请求对象,用于前后端数据交互的技术,可以在不重新加载网页的情况下,局部更新网页内容的技术
实现:
new一个XMLHttpRequest对象
open 打开通道,设置请求的url参数,一是请求类型,二是请求的url,可以带参数,动态传递参数到服务端
send发送请求
onreadystatechange只要状态改变就会调用,使用监听事件监听数据什么时候回来
9.get与post请求的区别
1.get在浏览器回退是是无害的,post会再次提交请求
2.post请求比get 请求慢
3.get请求URL地址会被标识
4.post更安全
5.post可以发送的数据更大
10.防抖与节流
1.防抖
- 原理:两次点击的时间间隔小于一定时间时,只执行后一次
- 实现:声明一个a变量不赋值,将一个定时器函数赋值给这个变量a,在未赋值前清除这个定时器,
- 应用场景:实现登录功能时
2.节流
- 原理:一段时间内函数只执行一次,例子(好比一个漏水的水龙头,隔一段时间会滴一滴水)
- 实现:在外部声明一个变量a,赋值为true,相当于是一个开关,使用一个if判断判断条件是变量a,内部放要执行的函数体,在一进入if的时候立马将变量a赋值为false,再用一个定时器,内部将变量a变为true
- 应用场景:无限上拉刷新