js三座大山:原型和原型链 作用域和闭包 异步和单线程
引用类型:对象 数组 函数 因为指针引用的是一个空间 所以叫做引用类型 目的是为了避免浪费很大的内存空间 引用类型可以无限制扩展属性
typeof (undefined string number boolean object function)只能区分值类型 但是不能区分引用类型 对象和数组{}[]null均打印object
变量计算:强制类型转换值类型转换
1.字符串拼接
var b = "110" +10
2.==
100 == "100"
0 == ""
null == undefined
3.if语句0 nan undefined null "" false
4.逻辑运算
!window.abc a=100 !!a true
js中的内置函数 不考虑浏览器的环境单纯作为语言来讲内置了构造函数 Number String Boolean Object Function Array Date RegExp Error内置函数的作用原型链
构造函数的特点 函数名称大写 默认会有return this
重点关注this 对象无限添加属性
image.png
原型规则 4条
1.所有的引用类型(数组 对象 函数)都具有对象特性,既可以任由扩展属性除了null
2.所有的引用类型(数组 对象 函数)都有一个proto属性!隐式原型!,属性值是一个普通对象 所有函数都有一个prototype属性,属性值也是个对象
3.所有引用类型(数组对象函数)proto属性值指向他的构造函数“prototype”属性值
4.试图在好一个对象的属性时 如果对象本身没有会去查找自身的proto隐式原型查找
image.png
for(i in obj) 高级浏览器屏蔽了来自原型的属性只拿自身的属性
obj.hasOwnProperty(i)属性是否为自身的
原型链
image.png
image.png
1.准确判断一个变量是数组类型
intanceof判断一个函数是否是一个变量的构造函数
[] intanceof Array
2.写一个原型链继承的例子
就是将构造函数的显示原型重新赋值一个对象
image.png
3.描述new一个对象的例子
创建一个新对象 this来引用这个对象然后就可以给this扩展属性 类似于a={} a,age =18
image.png
练习
image.png image.png
json:也是js中的内置对象和math一样是内置对象而不是内置函数 JSON.stringfy和JSON.parses 也是一种数据格式
image.png
1.Math.random在前端清除缓存作用
image.png
image.png
Date.now()和getTime是一样的
this要在执行时才能确认值,定义时无法确认,执行时的意思是一个函数加括号 在这之前函数仍然处于定义状态如果3,4,5行写了错误 在前6行代码是不会报错的因为没有编译
箭头函数的this为定义时的对象也就是一直要找到外层函数看外层函数在什么对象的下面所以闭包中使用箭头函数会将this指向正确的对象 而闭包中的函数是普通函数调用所以指向window 以下的例子可以很好理解这句话
image.png
1.构造函数 this指向new 后面的新对象
image.png
2.对象属性 下面的第一个例子 this指向调用者
image.png
3.普通函数 window
image.png
4.call apply bind call和apply的区别在于后面参数传递apply为数组 而bind与这两个的区别在于返回的是函数需要.bind(aaa)()执行
image.png
image.png
函数表达式
image.png
image.png
前6行代码 console.log(this)并不能确定this的值
作用域:js没有块级作用域 只有函数和全局作用域
作用域链:当前作用域没有的变量即自由变量,于是去父级作用域去找,函数的父级作用域是函数定义时的作用域不是执行的时候
image.png
闭包:函数 作为返回值
image.png
打印100的原因 函数的this是执行时确定所以this的当前环境是window而函数变量是定义时将会去父级查找所以打印100
闭包的使用场景:函数作为参数传递 函数作为返回值
image.png
1.变量提升变量定义/函数声明
image.png
声明提前 也就是相当于var age; age = 100 函数定义就是函数声明所以就是把整个函数定义提前 而变量是变量定义+变量赋值两个操作 所已 这就是为什么函数表达式不会起作用比如var a = function(){} 提前的将是 var a = undefined
arguments
10个a标签都初始化好之后放进页面中,监听函数的执行时间是不确定的是我们点击的时候当我们点击的时候i已经循环到10 所以结果将是每个标签点击都为10
image.png
创建 函数作用域 声明了10个函数
image.png
闭包的应用 封装变量收敛权限
判断用户是否是第一次加载对list进行封装 函数外部是拿不到list的 所以你将不会改到list收敛权限
image.png
执行上下文:一段<script>标签或者一个函数将会生成执行上下文
异步单线程:js是单线程所以才有的异步 alert(200)会阻塞程序的执行
对比异步和同步
image.png
image.png
1.setTimeout 同步和异步的区别是阻塞
2.前端使用异步的场景有哪些,什么时候需要异步
在可能发生等待的时候 1.setTimeout/2.网络请求 ajax<img>加载/3.事件绑定不一样的地方是可以执行多次 等待过程中不能阻塞程序运行
image.png
image.png
单线程 下图没有时间的设置和设置为0是一样的 单线程一次只能做一件事打印100 300 200
image.png
其他知识点
image.png
image.png
image.png
jswebapi
回顾js基础 表面看来并不能用于工作中开发代码 也就是浏览器要遵循ecma标准也要遵循W3c标准(dom bom 事件绑定 ajax 存储)w3c没有规定js基础相关的 东西他和ecma是不重合的W3c不管变量类型 原型 作用域和异步 语法和原来是ecma来管 w3c只负责定义浏览器中js操作页面的api和全局变量
image.png
image.png
image.png
dom本质:html和xml规则是一样的浏览器拿到html的页面的时候需要把这个页面渲染并且还要让浏览器能解析js 浏览器最喜欢处理结构化的东西拿到html的代码的时候就会将他结构化dom html代码就是字符串浏览器将他结构化成js/浏览器可识别的东西,如果js不能识别和操作那js将不能及逆行
image.png
dom操作
1.dom是哪种基本的数据结构 树形的数据结构
2.dom操作常用的api
针对树结构 :新增节点/获取父节点/获取子节点/删除节点/遍历
移动的时候 p2将不会在原来的地方存在
image.png
image.png
3.dom的attr和property的区别
image.png
image.png
attribute image.png
attribute改的是html文档中的标签属性 而property改的是js对象内的属性是两个完全不一样的东西
image.png
nodeType 是数字类型 nodeName 是英文名字的描述
image.png
Bom拿到的是关于浏览器一些信息
navigator.userAgent
image.png
screen
image.png
location
image.png
history
image.png
1.检查浏览器类型
navigator.userAgent()
2.解析url的各部分
location.href
location.protocol
location.pathname
location.serach
location.hash
image.png
事件绑定(通用事件绑定 事件冒泡 代理)
面试的时候尽量不要说自己用框架做过什么东西
1.编写一个通用的事件监听函数
image.png
ie低版本使用你的是attachEvent因为ie低版本使用的是自己的标准,
2.事件冒泡流程
不用事件冒泡做的 方式 很繁琐
image.png
事件冒泡:将时间绑定在div1上 冒泡的机制是p1 div1 body冒泡是事件向上 上图的效果点击激活是先alert激活 然后取消不满足我们的要求 也就是要阻止点击激活的时候的冒泡e.stopPropatation() propagation:蔓延
其余相同的时间将会冒泡到body
冒泡事件的应用 代理
虽然我们在div1上绑定的监听事件 但是target是告诉我们在哪里触发的事件即a标签
target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口
image.png
image.png image.png
image.png
代理的好处:代码简洁 减少浏览器内存占用
3.对于无限下拉加载图片的页面,如何给每个图片绑定事件 代理
事件冒泡流程:
dom属性结构 事件冒泡 阻止冒泡 代理
ajax(XMLHttpRequest 状态吗说明 跨域)
1.手动编写ajax 不依赖第三方库
3-10行为异步 异步的意思是最后执行 send之后xhr开始舰艇状态变化 ie低版本使用得是ActiveXObject
var xhr = new XHMLHttpRequest()
xhr.open('get','/a.txt',false);
xhr.onreadystatechange= function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
status是http标准的状态码
image.png
console.log(xhr.responseText)
}
}
}
xhr.send(null)
image.png
2.跨域的几种实现方式跨域的原理(什么是跨域 jsonp)
浏览器同源策略 不允许ajax访问 其他接口 比如我们自己的网站用ajax来访问别人的接口
image.png
https 端口是443
防盗链 就是我们从自己的网站使用百度的图片是加载不出来的
a标签
image.png
img标签用于打点统计统计网站可能是其他域
image.png
image.png
jsonp实现原理
image.png
服务器动态拼一个js文件返回给我们
2服务端色湖之http header
image.png
存储
1.cookie sessionStorage localStorage的区别
cookie本身用于客户端和服务器端通信的 但是它有本地存储的功能于是被借用
image.png image.png
sessionStorage在浏览器中存储本地只要浏览器关闭将会清理localStorage不会
image.png
区别:容量
cookie会被携带到ajax中
api易用性
开发环境
1.页面的加载过程
从输入url到得到html的详细过程:加载资源的形式/加载一个资源的过程/浏览器 渲染页面的过程
形式2种:输入url加载html加载html的静态资源js图片 浏览器根据DNS服务器得到域名的IP地址,向这个ip的机器发送http请求,服务器收到处理http请求 ,浏览器的到返回的内容,浏览器根据html结构生成dom树 再根据css生成cssom 在将dom树和cssom整合形成rendertree,最后浏览器根据rendertree开始渲染 遇到script会阻塞 渲染因为js有权利改变dom的结构
window.onload和DOMContentLoaded的区别
页面加载的几种样例
首先加载页面的11行代码html代码,然后浏览器开始一步步从头分析 分析道link标签时 去加载css然后生成cssom的一个东西浏览器就会知道在div上要添加这样的样式,紧接着在继续解析的时候因为css已经解析完了再去渲染div生成divdom结构的时候就会将样式一次性渲染出来
为何把css放在head中:加载完css浏览器 知道规则在渲染body的时候将会把样式直接渲染出来,如果放在最后的话将会第一次显示默认的情况过了一会按照样式渲染
image.png
首先输入url加载12代码 然后浏览器开始 解析进入body渲染 到底9行的时候加载script 并执行这一行 js代码阻塞后续代码的渲染,js执行 完之后然后继续向下渲染
js放在最后 是因为不会阻塞html的结构渲染 第二是因为 script可以拿到所有的标签
image.png
首先加载html的内容 然后开始渲染加载到图片的 时候异步请求 但是并不会阻碍整个dom的渲染
window.onload必须加载完所有资源
DOMContentLoaded dom渲染完既可以执行不需要等待视频图片
image.png
2.性能优化
(1)多使用内存缓存 减少cpu计算 减少网络请求 入手(加载页面静态资源的压缩合并,静态资源缓存:本地缓存,使用cdn让资源加载更快因为cdn是不同区域的网络优化,ssr后端渲染,数据直接输出到html中,页面渲染 css放前面 js放后面 懒加载 下拉加载 减少dom操作多个操作合并在一起执行无论是查询还是插入 比如查询的时候存入变量 事件节流 尽早执行操作donmcontentloaded)
优化样例讲解
1.构建工具合并静态资源
2.缓存通过连接名称控制缓存 不更换资源的名字 浏览器会帮我们缓存
4.ssr后端渲染 jsp把数据直接输出到页面中 而不是ajax请求
image.png
5.缓存dom查询 第一个是每次循环都将执行dom查询做了10次
image.png
image.png
事件截流
每次键盘输入的时候后触发change操作,但是有的人打字很快我们要做的就是当输入完成之后再去触发change操作
每次都清除上次的setTimeout事件 也就是在短时间内上一次的事件将永远不会触发只会执行最后一次的setTimeout事件
image.png
image.png
3.安全性
xss跨站请求攻击 再发布文章的时候的时候插入一段js代码 获取查看者的cookie发送到我自己的服务器 基本原理就是在向网站发布东西的时候提交 js代码 最好的预防就是将<替换成 其他内容
xsrf 和之前css看的不要将请求放在链接中的一个意思增加验证流程
image.png
简历 过程
项目经历和解决方案
个人博客
开源项目
es6语法
原型上面的this是指new新的对象
image.png
Object.assign({最后生成的对象},{json对象}) 作用就是合并对象
image.png
es6中的构造函数在new的时候就会自动立即执行
image.png
类里面的函数前面没有function showName(){} const a = class{}
类不会预解析 下面的代码会报错
image.png
关于this
下面的this打印为undefined 矫正的方法为1.在构造函数里this.showName.bind(this)
image.png
严格模式下函数中的this将会是undefined 也就是解释了为什么在类中结构出来的函数中的this将会是undefined
image.png
image.png
类中的getter和setter set会监听到对象添加属性的操作 get会监听到获取的操作 用途实在底层封装框架
image.png
类身上的方法为静态方法
image.png
静态方法也会可以给子类调用
原方式函数继承
image.png
function Person(name){
this.name = name;
}
Person.prototype.showName = function(){ return ${this.nane}
}
function Student(name,skill){
//属性继承
Person.call(this,name);
this.skill = skill;
}
//方法继承
Student.prototype = new Person()
es6继承 extends
子类的构造函数必须执行一个函数就是super() 来执行父类的构造函数 否则会报错因为子类的构造函数将会把父类的构造函数给覆盖了
image.png
image.png
添加自己的属性
image.png image.png
继承:拖拽的例子
image.png
es6中的块级作用域 解决点击li监听函数弹出不一样的数字问题(1.let是利用块级作用域if for后面的花括号就是一个块 2.使用立即执行函数创建函数作用域解决)
let 相当于 var 但是没有预解析 同一个作用域里不能重复定义,在for循环的时候是父级作用域括号里是f花括号是子
const 在定义的时候必须要先赋值
对象引用的关系是不可以再重新引用其他的对象地址 但是对象内部的属性可以
Object.freeze 定一个数组不能去修改const arr = Object.freeze(["aaa","bbb"])
arr.push("a")将会报错 不能扩展
image.png image.png
下图将会报错
image.png
没有块级作用域的时候我们是拿立即执行匿名函数来模拟的
解构赋值
let [a,b,c] = [12,5,6]
左右两边,结构格式要保持一致,数组的解构按从左至右依次赋值
解构json 解构对象的时候需要属性依次对应
let json = {
name="strive",
age:18
}
let {name,age}= json
给默认值 但是对null会无效 null会赋值给c
image.png image.png
数组里可以交换位置
image.png
window和top是相同的
解构还用在import {}
函数传参解构
image.png
//函数传参给的默认值 如果不给的话将会报错 相当解构左右两边不等 如给了默认值当函数没有传参的时候将取默认值
function show({a = 1,b = 2} = {}){}
show()
4.字符串模板及新增
优点可以随意换行
image.png
str.indexOf 返回索引位置 -1
str.includes("a")返回 bool
image.png
检测 是否是以http开头
str.startsWith("http") str.endsWith
str.repeat(3) 重复3次
str.padStart(整个字符串长度,填充内容) 向前填充
"str".padEnd(6,"xxx")
image.png
函数变化
函数的默认参数
这个传值了 只有不给的时候才是没传
image.png
会报错 函数的参数将是默认定义的 和for循环有差别
image.png
扩展运算符 重置 剩余运算符...
对数组 和对象都管用
image.png
排序
image.png
剩余 剩余的意思是只能放在最后一个
image.png
复制数组 let arr = [1.2,3]
let b = [...arr]
image.png
函数真正的变化是箭头函数
当没有花括号的时候默认返回
image.png
完整的箭头函数
image.png
会执行undefined setTimeout由window执行
image.png
setTimeout 相当于一个数组 把方法存到数组里面 然后过段时间拿出来在全局环境下运行
image.png
let和const定义的变量不属于window
箭头函数中的this会绑定定义函数时候坐在的对象,不再是运行是所在的对象了
image.png
arguments在箭头函数中不存在 利用扩展运算符
image.png
箭头函数不能做构造函数使用 不能new
image.png
数组的热闹循环
数组最常见的就是循环
arr.forEach
arr.forEach(()=>{},123)回调函数是每循环一次调用一次
arr.filter
过滤:也是学要return的 过滤不想要的元素如果回调函数返回true该item项将回留下来
image.png
arr.some 数组里有一个选项符合条件就返回true 类似于查找的功能
image.png
arr.every 数组里面的所有元素都符合条件才会返回true
以上接受的参数一模一样 可以接受两个参数,第一个为回调函数 第二个是this的指向改变,第二个参数的几率很小
image.png
image.png
箭头函数绑定的this是定义时的this 不会改变 一下的结果打印还是window
image.png
arr.reduce 接受的参数 前一个和当前的item 项 index arr
reduce也是一个循环 求数组和
let arr = [1,2,3.4]
arr.reduce((pre,cur,index,arr)=>{ return pre+cur})
image.png
arr.redeceRight 打印81
image.png
for of 循环 最后一个[key,value]为数组解构
image.png image.png
数组另增新的其他的东西
将类数组转为数组的方式,并且下标是0,1,2
类数组典型的特点是有length
image.png image.png image.png
2.Array.of()将一组值转为数组 类似于三点
image.png
3.数组本身的方法
find找出第一个复合条件的数组成员,如果没找到返回undefined
let arr = [1,2,3]
arr.find((val.index,arr)=>{ return val>2}) //打印3
findIndex没找到返回-1返回第一个符合条件的位置
3fill (填充的东西 开始位置 结束为止)
image.png
4.arr,IndexOf
arr.incluldes("a") 返回truefalse
findIndex传得是函数 indexOf是value项 返回的将是第一个符合条件的索引项位置
对象
对象的简介语法
image.png
对象里面不能用箭头函数
image.png
Obejct.is比较两个值相等 NaN
Object.is(NaN,NaN)
image.png
image.png
Object.assign 用来合并 复制对象
let json = {a:1}
let json 2 = {b:1,//a:2} 后面会覆盖前面的
let json3 = {c:3}
Object.assign({},json1,json2,json3)
Promise 主要的作用是解决异步回调问题,传统方式大部分用回调函数,事件
就是回调嵌套回调在嵌套回调
image.png
image.png image.png
image.png
image.png
image.png
Promise.all必须确保所有的promise都是resolve的状态即都是成功的状态
image.png
symbol和generator
let syml = Symbol("aa") 不能new 他不是构造函数
image.png
json 使用for in循环 不能输出symbol的属性
image.png
image.png
generator 也是个函数 目的是解决异步问题 深度嵌套问题同promise 现在使用async
区分generator函数和普通函数*
function * show(){
yield //产出
}
genrator是分步骤完成的 done是说该函数是否完成,遇到return 完成
image.png
image.png
image.png
以上是手动调用 for..of自动遍历generator 但是不会遍历return的东西只会遍历yield的东西 还可以配合解构赋值
image.png
image.png
b是 剩余参数组成的数组
image.png
image.png
image.png
解决异步 第一步的结果传到第二步请求中
image.png
image.png
async
image.png
promise解决多层回调
image.png
generator解决多层回调
image.png
image.png
image.png
image.png
任何与网络请求有关的东西都try catch
以下三个网络请求没有必然关系的时候可以这么用 因为不能保证哪个网络请求先执行完后执行完
image.png
网友评论