一、变量的类型和计算
1.变量类型
//值类型
let a = 200;
let b = a;
a = 100;
console.log(a, b)
// 援用类型
let a = { age: 24 };
let b = a;
b.age = 25;
console.log(a, b);
值类型和援用类型的区别?
值类型
,值类型的复制就是复制栈里的value
。援用类型
的复制复制的是堆的援用内存地址
。
为什么?
值类型的占据内存比拟小,援用类型占据的内存可能会十分大,不利于复制,从CPU和性能思考把援用类型和值类型的复制的形式给分离出来。(js引擎)
哪些是值类型?哪些是援用类型?
let a;// undefined
const b = "string";
const c = false;
const n = 100;
const s = Symbol('s');
const obj = { age: 24 };
const arr = ["1", "2", "3"];
const n = null; // 非凡的援用类型,指针指向的是空地址
// 非凡援用类型 不用于存储数据,所以没有拷贝,复制函数之说
function fn() { }
typeOf 类型判断
所有的值类型,函数
援用类型只能到Object
手写深拷贝
重点1:初始化result
重点2:应用递归
obj1 = {
name: "胡子银",
level: "p0"
};
function deepClone(obj = {}) {
if (typeof obj !== 'object' || typeof obj == null) {
return obj;
}
// 初始化返回后果
let result;
if (obj instanceof Array) {
result = []
} else {
result = {}
}
// 开始拷贝
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 保障key 不是原型的属性
// 递归调用
result[key] = deepClone(obj[key]);
}
}
return result;
}
2.变量计算
字符串拼接
const a =100+10 // 110
const b = 100 +'10' // '10010'
const c= true + '10' // 'true10'
==运算符
100 == '100' // true
0 == '' // true
0 == false // true
false =='' // true
null == undefined // true
总结: 除了null
用 ==
其余都用===
if语句和逻辑运算
truely 变量与 falsely 变量 两次取反
二、原型和原型链
面向对象
类的继承:extends super 重写
隐式原型 与 显式原型
instanceof 是不是它构建的。父类。Object是所有的父类
Student.__proto__ === People.ProtoType // true
隐式原型 :Student.proto
显式原型:People.ProtoType
每个class都有显式原型,每个实例都有隐式原型,实例的隐式原型指向类的显式原型。
原型链
instanceOf
三、作用域和闭包
this 在不同场景下,如何取值?
手写bind函数
闭包在理论开发场景中的利用
什么是作用域?
变量的非法应用范畴。框外面的都能够。
作用域:
全局作用域
函数作用域
块级作用域 let const {}
什么是闭包?闭包会被作用到哪里?
作用域利用的非凡体现,有两种状况
函数
作为参数
被传递。函数
作为返回值
被返回。
总之,函数定义的中央和执行的中央是不一样的。
闭包:自在变量在函数定义的中央向下级作用域查找。而不是在执行的中央。
// 函数作为返回值
function createFun() {
const a = 100;
return function () {
console.log(100);
}
}
const fn = createFun();
const a = 200;
fn();
// 函数作为参数被传递
const a = 100;
function param() {
console.log(a);
};
function close(param) {
const a = 200;
param();
};
// const clo = new close(param);
close(param);
this的几种赋值状况
函数在执行的时候决定。
箭头函数 ==> 取的是下级作用域的值
bind call 的区别
function fn() {
console.log(this);
}
const fnbind = fn.bind({ x: 200 },10,20,30);
fn();
fn.call({ x: 100 });
fnbind()
作用域相干的面试题
this的应用场景,console.log(this)
1、一般函数被调用 // window
2、作为对象办法 指向对象
3、bind,call,apply 把this的指向作为参数传递进去。(传进去的就是this)
4、箭头函数 this指向上一层作用域
5、在class中调用
手写bind函数
JavaScript
中的Array.prototype.slice.call(arguments)
能将有length属性的对象转换为数组
Function.prototype.bind = function () {
const args = Array.prototype.slice.call(arguments);
// 获取数组的第一项
const t = args.shift();
//此处this是fn1.bind()中的fn1
const self = this;
return function () {
return self.apply(t, args);
}
}
闭包中的利用
闭包: 自在变量在函数定义的中央向下级作用域查找。而不是在执行的中央。
闭包暗藏数据,只提供api,闭包中的数据,被暗藏,不被外界拜访。
创立缓存,set,get,调用get办法取到的变量是,而不是
let形成了块级作用域
四、异步
根底
const imgUrl = "0000";
function loadImg(src) {
return new Promise((resolve, reject) => {
const img = document.createElement('img');
img.onload = () => {
return resolve(img);
}
img.onerror = () => {
return reject(new Error("图片加载失败"));
}
img.src = img;
})
}
loadImg(url).then((img) => {
console.log(img.width);
return img;
}).then((img) => {
console.log(img.height);
})
进阶
事件轮训,事件循环
js是单线程,异步要基于回调实现,event Loop就是依据异步回调的实现原理
js是怎么执行的?
call Stack:调用栈 用完就清空
web apis:如setTimeout dom bom等
callback queue:回调函数队列
event loop:
总结:
同步代码,一行一行放在Call Stack执行
遇到异步,会先“记录”下,期待机会(定时、网络申请等);
机会到了,就移到Callback Queue
如Call Stack为空(即同步代码执行实现)Event Loop开始工作
轮询查找Callback Queue,如有则移到Call Stack 执行
而后持续轮询查找
dom事件也是基于Event Loop。
Promise
then 失常返回resolved ,外面有报错则返回rejected
catch 失常返回resolved,外面有报错则返回rejected
总结:
三种状态,状态和体现
then和catch对状态的影响(重要)
then和catch的链式调用(常考) 只有是没报错,就是resolved。
async await
异步回调
promise也是基于回调。async-await彻底毁灭了回调。
async和promise的关系
- 执行async函数,返回的是Promise对象
- await相当于Promise的then (如果间接返回的数据,相当于 Promise.resolve(400))
- try...catch可捕捉异样,代替了Promise的catch
async await是语法糖 异步的实质还是回调函数
还是基于回调函数,还是基于event Loop
for …of
for…in(以及forEach for)是惯例的同步遍历 ????
for…of 罕用于异步遍历?????
宏工作与微工作
宏工作与微工作
- 宏工作:setTimeout,setInterval,Ajax,DOM事件
- 微工作:Promise,async/await
- 微工作执行的工夫要比宏工作执行的工夫要早。
为什么微工作比宏工作的执行工夫要早?
event Loop 与 DOM事件 渲染。js是单线程的。也就是说event Loop与Dom渲染共用同一个线程。
宏工作在DOM渲染后触发,如setTimeout();
微工作,在DOM渲染后,如setTimeout();
为什么宏工作在DOM渲染后触发,微工作在DOM渲染前触发?
宏工作与微工作的基本区别
从event Loop解释为什么微工作比宏工作的执行工夫早。
微工作是浏览器规定的
宏工作是es6规定的
寄存的中央不一样。
总结:
五、JS-WEB-API
JS = ECMA (ECMA262规范)+DOM(w3c) +BOM (w3c)
W3C规定web-api,css,html,网络申请的货色还挺多的。
5.1DOM
document object model
题目:
DOM是哪种数据结构
DOM操作的罕用API
attr和property的区别
一次性插入多个DOM节点,思考性能
dom的实质
dom节点的操作
const div1 = document.getElementById("app1"); //
const div2 = document.getElementsByClassName("appclass");
const divList = document.getElementsByTagName("div"); // list
const pList = document.querySelectorAll("p"); //
console.log("div1:", div1);
console.log("div2", div2);
console.log("divList:", divList);
console.log("pList:", pList);
// property 模式 批改属性值
console.log(pList[1].style.width);
console.log(pList[1]);
// attribute 模式 批改属性
pList[1].setAttribute("data-name", "imook");
console.log(pList[1].getAttribute("data-name"));
pList[1].setAttribute("style", "font-size:50px");
打印进去的后果比照,间接获取的dom节点,list的会有属性
dom 构造操作
DOM性能
- DOM操作十分低廉,应该防止常常对DOM元素进行操作。
- 对dom查问做缓存。
- 将频繁操作改为一次性操作
const listNode = document.getElementById("app1");
const flagNode = document.createElement("ul");
for (let i = 0; i <= 5; i++) {
const li = document.createElement("li");
li.innerHTML = "innerHtml";
flagNode.appendChild(li);
};
listNode.appendChild(flagNode);
5.2 BOM
题目
如何辨认浏览器的类型?
ua
剖析拆解url的各个局部。
// navigator
console.log(navigator.userAgent); // ua查看计划
// screen
console.log(screen.width);
// location
console.log(location.href); // 整个网址
console.log(location.host) // 域名
console.log(location.search); //
console.log(location.hash); // 哈希 #
console.log(location.pathname); //
// history
history.back();
history.forward();
5.3 事件 事件绑定和事件冒泡
通用的事件绑定函数
<button id="btn1">点击</button>
<script>
var btn = document.getElementById("btn1");
function bindEvent(ele, type, fn) {
ele.addEventListener(type, fn);
};
btn.bindEvent("click", e => {
// 阻止默认行为
e.proventDefault();
// e.target
console.log(e.target);
console.log("事件绑定");
})
</script>
事件冒泡
事件代理
把事件绑定到父元素上,点击子元素,弹出子元素的interhtml
代码简洁,缩小浏览器的内存应用,然而不要滥用。
5.4 AJAX
GET
const xhr = new XMLHttpRequest();
xhr.open("GET", "./data.json", true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
alert(xhr.responseText);
} else {
console.log(xhr.responseText);
}
}
}
xhr.send(null);
POST
const xhr = new XMLHttpRequest();
xhr.open("POST", "./login", true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
alert(xhr.responseText);
} else {
console.log(xhr.responseText);
}
}
}
const postData = {
"name": "狂徒张三"
}
xhr.send(JSON.stringify(postData));
301 永恒重定向
302 长期重定向
304 资源有,反复,浏览器用本人的。事关性能优化
404 地址错了
403 没有权限
浏览器的同源策略
什么是跨域(同源策略)?
JSONP
CORS(服务端反对)
jsonp的次要内容有两点:
1、script能够跨域
2、服务器拿到url能够动静的返回一些内容
cors
是服务端设置申请头,容许哪些进行拜访。
理论我的项目中ajax的罕用插件
jqyery.ajax()
fetch()
axios
xmlhttprequest
5.5sessionStorage与localStorage的区别
题目:形容cookie localStorage sessionStorage 的区别
- cookie
cookie的价值不在于本地存储,而在于与服务端的通信。是被借用来作为本地存储的工具。因为每次申请都须要带着cookie,所以会减少申请的数据量,而且cookie的最大的存储空间是4kb,只能通过document.cookie来批改。过于简陋。
批改的形式:雷同的key,笼罩,不同的key,追加
- sessionStorage与localStorage
localStorage数据会永恒存储,除非代码或者手动删除
sessionStorage数据只存在于以后会话,当浏览器敞开就清空
6、HTTP
6.1 http的几个面试题
常见的状态码:
301 永恒重定向
302 长期重定向,
举例1:在百度检索了一个css教程,hover下来的链接点击当前,先是拜访百度的url而后浏览器的location再跳转到真正的目标链接地址、。
举例2:还有短链
304:浏览器曾经申请过了,能够应用本地的,本地的没过期
403:没权限
404:地址谬误
5 **:服务端
对于协定和标准:就是一个约定和标准
6.2 http method
传统method
get
post
当初的method
get 查
post 创立新的
patch
delete
restful API
- 一种新的API设计办法(早已推广应用)
- 传统API设计:把每个url当做一个性能
- Reatful API设计:把每个url当做一个惟一的资源标识
尽量不要应用参数,应用method作为类型
6.3 http 常见headers
Request Headers
Request Headers
缓存相干的Headers
6.4 http为什么须要缓存?
对于缓存的介绍
网络申请加载比较慢,cpu计算比拟快。性能优化的次要瓶颈就在于网络申请,当局部不须要被反复申请的资源被缓存,就能够缩小http申请,从而优化性能。
哪些资源能够被缓存?动态资源,(js,css,图片,与webpack打包加的hash无关,只有内容扭转了,才会再次更改)
http缓存策略(强制缓存+协商缓存)
1、强制缓存
cache-contral 强制缓存,管制强制缓存的逻辑
cache-control:max-age=2592000 (秒)
max-age:过期工夫
no-cache : 本地不做缓存
no-store:本地不缓存,服务器端也不缓存。
对于Expires
2、协商缓存(比照缓存)
Last-Modified: 最初一次批改的工夫
Etag: 人类的指纹,惟一的标识,字符串
两者共存,会优先应用Etag,Etag会更加精准。
总结: 就是申请服务端,问问服务端本地的能不能用。
刷新操作形式 对缓存的影响
失常操作:url的后退后退; 都无效
手动刷新:强制缓存生效,协商缓存无效
强制缓存:contral + command + 2 都生效
发表回复