一、第一部分
1.1值类型和引用类型
1.1.1值类型都是变量,通过在栈中进行存储,值类型在内存中所占的空间小;a=100,直接给a分配100的值空间;b=a,直接给b也分配一个100的值空间;因此a=200,直接修改a的值空间即为200;而b的值空间不变还是100
引用类型在内存中所占空间较大,一般通过栈和堆进行存储,给a={age:20},会在堆中申请一个内存地址,指向这个对象{age:20},;也就是说,a中存储的并不是一个对象,而是一个内存地址1,这个内存地址1,指向这个对象。把b=a,b也就指向这个内存地址1,;当b.age=21,b就把这个内存地址1改成了指向对象{age:21}了;因此此时的内存地址1已经被改成指向对象{age:21};a.age打印为改变后的对象{age:21}。
1..1.2 常见值类型
注意:使用const声明变量时必须赋值,要不然会报错
1.1.3常见引用类型
注意:函数也可当做一个特殊的类型
1.2 typeof运算符和深拷贝
1.2.1 typeof运算符
注意:typeof可以判断所有的值类型
也可以判断 函数类型和引用类型
引用类型只能识别到对象‘object’,具体还得使用其他方法
1.2.2 深拷贝
1.2.2.1 先看下浅拷贝:
//shanghai
也就是说上面的例子是符合引用类型的,改变了共同指向的内存地址指向的对象
1.2.2.2 深拷贝:不改变原来内存地址指向的对象
先使用typeof判断obj是null还是(数组和对象)
如果typeof obj是null不是(数组和对象),就返回obj;
如果instanceof 判断是数组,就返回[];否则返回{};
开始for循环遍历数组或者对象的每个值,要先hasOwnProperty过滤掉不是原型上的属性,保证key是obj自己本身 的属性,在对其属性进行一一深拷贝递归调用;
返回所得结果result:
1.3 变量计算
主要涉及到的有:字符串拼接、==、if语句和逻辑运算
1.3.1 字符串拼接
1.3.2 == 运算符
1.3.3 if语句和逻辑运算
真变量:!!a === true 的变量;
假变量:!!a ===false 的变量;
假变量都有哪些?
逻辑运算符
上面的例子:1.因为10是变量,所以继续看后面的,0 是假变量,所以返回0;
2.' '是假变量,继续看后面,'abc'是真变量,返回'abc';
改一下:
1.console.log(0&&) ;
//0
因为0是假变量,直接返回0
2.console.log('abc' || ' ') ;
//'abc'因为'abc'是真变量,直接返回'abc'
总结:
1.typeof能判断哪些类型?
答:1.识别所有值类型
2.识别函数
3.判断是否是引用类型
2.==何时用?===何时用?
答:除了判断==null之外,其他一律用===
3.值类型和引用类型的区别?
面试中会出题,比如:
其中x1=obj1.x是干扰判断,值类型赋值,直接分配内存空间;obj2.x=101,引用类型赋值,改变了与obj1共同指向的内存地址指向的对象,修改为{x:101}
4.手写深拷贝
答:首先判断是值类型还是引用类型;再注意判断obj是数组还是对象;递归
第二部分
题目:
1.如何精准判断一个变量是不是数组?
2.手写一个简易 的jQuery,考虑插件和扩展性
3.class的原型本质,怎么理解
知识点
1.class和继承
2.类型判断instanceof
3.原型和原型链
2.1 class
2.2 继承
extends、 super、扩展或重写
2.3 类型判断-instanceof
通过instanceof判断引用类型,前者是否是后者class构建出来的;或者说后者class是前者class构建出来的父类。
注意:Object是所有类的父类
2.4 原型
.prototype叫显式原型
_proto _叫隐式原型
原型关系:
1.每个class都有显式原型prototype
2.每个实例都有隐式原型_proto _
3.实例的_proto _指向对应class的prototype
基于原型的执行规则:
1.获取属性xiaoluo.name或执行方法xialuo.sayHi()
2.先在自身属性和方法上寻找
3.如果找不到则自动去_proto _中查找
2.5 原型链
再看instanceof
可以顺着xialuo能否对应到class的原型上的显式原型上;
比如,xialuo instanceof Studnet可以找到对应的显式原型Student.prototype;Student instanceof People可以找到对应的显式原型People.prototype;People instanceof Object可以找到对应的显式原型Object.prototype;
问题:
1.如何准确判断一个变量是不是数组?
答:使用instanceof,结合原型链图理解
2.手写一个简易的j Query,考虑插件和扩展性
答:
3.class的原型本质,怎么理解?
答:
1.原型和原型链的图示
2.属性和方法的执行规则
小结:
1.class和继承,结合上面手写jQuery的示例来理解
2.instanceof
3.原型和原型链:图示和执行规则
第三部分
题目:
1.this不同的使用场景
2.手写bind函数
3.实际开发中闭包的应用场景,举例
4.场景题:创建10个a标签,点击时候弹出对应的序号
知识点
作用域和自由变量、闭包、this
作用域
作用域分为:全局作用域、函数作用域、块级作用域
3.1作用域:
自由变量:一个变量在当前作用域没有被定义,但被使用了,那怎么办?可以向上级作用域,一层一层一次查找,直到找到为止,如果到全局作用域都还没找到,则报错 xx is not defined
3.2 闭包:
作用域应用的特殊情况,有两种表现:1.函数作为参数被传递2.函数作为返回值被返回
注:所有自由变量的查找,是在函数定义的地方,向上级作用域查找,而不是在执行的地方查找
因为fn()执行时,执行 create函数,create函数里面返回匿名函数打印a值,a值在匿名函数中没有找到,想上级 create函数查找a,找到了,a为100,因此打印a为100
因为执行print(fn)时,执行print函数,print函数里面执行fn(),执行fn()则执行fn函数,打印a值,a在fn函数中没有找到,向上级全局查找,找到了,a为100,则打印a为100
3.3 this
注意:this的取值是在函数执行的时候被调用,而不是在定义的时候
应用场景:作为普通函数被调用、使用call 、apply、bind被、作为对象方法被调用、在class方法中调用、箭头函数中
因为fn1()执行,打印的this是去全局的,所以fn1()执行打印window;而执行fn1.call(),call里面可以改变this指向,里面传入了对象{x:100},所以打印的就是这个对象{x:100};而执行fn2(),bind里面也可以改变this指向,里面传入了对象{x:200},就打印这个对象{x:200},注意一点,bind有条件:需要返回一个新的函数fn2,执行这个新函数才可以使用,而call直接调用就可以使用
eg2:
因为sayHi()作为zhangsan的sayHi()方法被执行,使以返回这个对象;而下面的wait()里面有一个setTimeout()执行,也就是说执行zhangsan.wait()时,如果没有setTimeout(),就返回的是zhangsan这个对象,有setTimeout()就相当于作为一个普通函数被执行,而不是作为一个方法被执行,是setTimeout本身触发的执行,而不是zhangsan,因此,打印的是this是window
eg3:
这个跟上面那个唯一不同的是setTimeout()里面有个箭头函数()=>{},而箭头函数的this是取它的上级作用域的值,因此跟zhangsan.waitAgain()方法跟zhangsan.sayHi()方法一样,取得是zhangsan这个对象
eg3:
constructor里面的this代表的是创建的实例,sayHi()方法里面的this代表就是zhangsan对象
题目解答:
1.this不同的使用场景
答:1、当做普通函数被调用 2.使用call、apply、bind 3.作为对象方法调用 4.在class的方法中调用 5.箭头函数
2.手写bind函数
答:
3.实际开发中闭包的应用场景,举例
//100
4.场景题:创建10个a标签,点击时候弹出对应的序号
因为i是全局变量,而
a.addEventListener('click', function(e){
e.preventDefault()
alert(i)
})
事件是当点击才会触发该事件,所以for循环非常快早已遍历到10,因此每当点击事件发生前,i就是10,因此点击0-10,都弹出10
修改:
将i改成局部变量,使其在for循环块级作用域里面,每次for循环的时候就会形成一个块,每次的值都会不一样
4.异步
题目:
1.同步和异步的区别是什么?
2.手写用Promise加载一张图片
3.前端使用异步的场景有哪些?
知识点
1.单线程和异步
2.应用场景
3.callback hell 回调地域和Promise
4.1 单线程和异步
-
js是单线程语言,只能同时做一件事
2.浏览器和node.js已支持js启动进程,如web worker
3.js和DOM渲染共用一个线程,因为Js可修改DOM结构
4.遇到等待(网络请求,定时任务)不能卡住,需要异步,回调cakkback函数
例子1:
异步:
先执行同步的100,遇到等待一秒才执行的setTimeout函数,但异步不会阻塞后面300的执行,因此先100,再300,再等待1秒执行200
// 100 300 200
例子2.
同步:会阻塞代码的执行,alert()没有完成,后面的就没法执行
//先100,弹出200警告框,点击确认之后才会打印300
4.2应用场景
1.网络请求,如ajax场景
2.定时任务,如setTimeout定时器
4.3回调地域 callback hell
4.3 Promise
问题:
4.4 手写promise加载图片示例
eg1:加载一张图片
eg2:加载多张图片
4.5异步应用场景
1.网络请求,如ajax图片加载
2.定时任务,如setTimeout
先1,遇到等待1秒执行的setTimeout异步不会阻塞后面代码,打印3,再遇到等待0秒,也就是立即执行的的setTimeout异步,但依然是异步,因此还是执行后面的代码5,然后再执行立即等待的4,然后再是2
小结
1.单线程和异步,异步和同步的区别
2.前端异步的应用场景:网络请求&定时任务
3.Promise解决callback hell嵌套的问题
js基础总结
内容:
1.变量的类型和计算
2.原型和原型链
3.作用域和闭包
4.异步和单线程
题目:
1.typeof能判断哪些类型
2.何时使用===何时使用==
3.值类型和引用类型的区别
4.手写深拷贝
知识点:
1.值类型 VS 引用类型,堆栈模型,深拷贝
2.typeof运算符
3.类型转换,truly和falsely变量
原型和原型链题目:
1.如何准确判断一个变量是不是数组?
2.手写一个简易 的 jQuery,考虑插件和扩展性
3.class的原型本质,怎么理解
原型和原型链-知识点
1.class和继承,结合手写jquery的示例来理解
2.instanceof
3.原型和原型链:图示
4.this的不同应用场景,如何取值?
5.手写bind函数
6.实际开发遇到的闭包问题(0-10对应弹出)
作用域和闭包-知识点
1.作用域和自由变量
2.闭包:两种常见方式
&自由变量查找规则
3.this
4.异步同步区别?
5.手写promise加载图片
6.前端使用异步场景
异步和单线程-知识点:
1.单线程和异步,异步和同步的区别
2.前端异步的应用场景:网络请求&定时任务
3.promise解决callback hell
第四部分 JS Web API
1.DOM
DOM操作
题目:
1.DOM是那种数据结构?
2.DOM操作的常用API?
3.attr和property的区别?
4.一次性插入多个DOM节点,考虑性能?
知识点
1.DOM本质
html解析出来的一棵树
2.DOM节点操作
先是获取DOM节点,再attribute,property
获取dom节点?
1.通过getElementById获取;
2.通过getElementsByTagName获取;
3.通过getElementsByClassName获取;
4.通过querySelectorAll获取;
dom节点的property:
dom节点的attr:
总结:
property
和attribute
区别:
property
:修改对象属性,不会体现到html结构中;
attribute
:修改html``属性,会改变
html结构,两者都有可能引起
DOM重新渲染,建议尽量用
property`
3.DOM结构操作
3.1新增/插入节点
新增
移动
3.2获取子元素列表,获取父元素
获取子元素列表:
const div1 = document.getElementById('div1')
const child = div1.childNodes
获取父元素
const div1 = document.getElementById('div1')
const parent = div1.parentNode
获取对应文本text节点:
3.3删除子元素
通过removeChild
:
div1.removeChild(child[0])
4.DOM性能
4.1DOM操作占用cpu较多,应避免频繁的DOM操作
4.2对DOM查询做缓存
4.3 将频繁操作改为一次性操作
DOM查询做缓存
//不缓存DOM查询结果
for(let i=0;i
//每次循环,都会计算length,频繁进行DOM查询
}
缓存DOM查询结果
const pList=document.getElementsByTagName('p');
const length=pList.length
for(let i =0;i
//缓存length,只进行一次DOM查询
}
将频繁操作改为一次性操作
const listNode =document.getElementById('list')
//创建一个文档片段,此时还没有插入到DOM书中
const frag = document.createDocumentFragment();
//执行插入
for(let x = 0;x < 10; x++){
const li = document.createElement("li");
li.innerHTML ="list item" + x
frag.appendChild(li)
}
//都完成之后,再插入到DOM树中
listNode.appendChild(frag)
总结
1.DOM是那种数据结构?
答:树(DOM树)
2.DOM操作的常用API?
答:DOM节点操作和DOM结构操作、attribute和property
3.attr和property的区别?
答:attribute是修改html结构,会改变HTML结构;property是修改对象属性,不会体现到html结构中;两者都有可能引起DOM重新渲染
4.一次性插入多个DOM节点,考虑性能?
答:通过frag文档片段,要考虑到先缓存再一起插入
2.BOM
题目:
1.如何识别浏览器的类型
2.分析拆解url各个部分
知识点
navigatior和screen
通过navigatior.userAgent
来查看浏览器信息
通过screen
查看屏幕信息:
location
location.href
:网址
location.protocol
:协议
location.host
:域名
location.pathname
:获取待path
路径
location.search
:获取常用参数
location.hash
:#后面的内容
history
history.back()
:程序后退
'hiotory.forward()':程序前进
3.事件绑定
题目:
1.编写一个通用事件监听函数
2.描述事件冒泡的流程
3.无限下拉的图片列表,如何监听每个图片的点击?
知识点:
3.1 事件绑定
const btn=document.getElementById('btn1');
btn.addEventListener('click',event=>{ console.log('clicked')})
event.target:获取触发的元素;
event.preventDefault() :阻止默认行为
3.2事件冒泡
点击激活,触发p1点击事件,打印出“激活 取消”
因为p1>div1>body,先是p1事件打印“激活”,再冒泡到body,触发body的点击事件,打印“取消”
加上阻止冒泡e.stopPropagation()
3.3事件代理
优点:代码简洁;减少浏览器内存占用(子元素较多需要设置监听时,只需要在父元素上设置一次即可)
注意:有了
event.preventDefault()
阻止默认事件,点击某个a2就不会跳转到#页面
3.4 编写一个通用的事件监听函数?注意this指向
描述事件冒泡的流程?
答:
1.基于DOM树形结构
2.事件会顺着触发元素向上冒泡3.应用场景:代理
无限下拉图片列表,如何监听每个图片的点击?
答:
1.利用事件代理;
2.用e.target获取触发元素
3.用matches来判断是否是触发元素
4.ajax
题目:
1.手写一个简易的ajax
2.跨域的常用实现方式
知识点:
1.XMLHttpRequest
2.状态码
3.跨域:同源策略、跨域解决方案
4.1XMLHttpRequest
在ajacx文件夹下的XMLHttpRequest文件夹下新建data文件夹,data文件夹下面再新建test.json;
访问
http://127.0.0.1:5500/ajax/XMLHttpRequest/data/test.json
实现get请求:
访问
http://127.0.0.1:5500/ajax/XMLHttpRequest/index.html
那么,POST请求:效果无法演示,代码如下:
0-(未初始化)还没有调用send()方法;
1-(载入)已调用send()方法,正在发送请求
2-(载入完成)send()方法执行完成,已经接收到全部响应内容
3-(交互)正在解析响应内容
4-(完成)响应内容解析完成,可以在客户端调用
xhr.staus
2xx-表示成功处理请求,如200;
3xx-需要重定向,浏览器直接跳转,如301 302 304;(301永久重定向,302临时重定向,304资源未被改变)
4xx-客户端请求错误,如404 403 (404 没有找到;403没有访问权限)
5xx-服务端错误(服务器程序有bug)
4.2 跨域
4.2.1什么是跨域?
1.ajax请求时,浏览器要求当前网页和server必须同源(安全)
2.同源:协议、域名、端口,三者必须一致
比如:
前端 :http://a.com:8080/;
后端:https://b.com/api/xxx;
4.2.2 加载图片css js可无视同源策略
1.
2.
3.
4. 可用于统计大点,可使用第三方统计服务
5.