一、变量的类型和计算
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 都生效