字节一
1 Router hash history
- hash原理:hash通过监听浏览器的onhashchange()事件变化,查找对应的路由规则
-
hash 就是url尾巴上的#号以及后面的内容, hash值改变不会导致浏览器向服务器发送请求,而且hash改变会触发
hashchange事件
-
hash虽然出现url中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash不会重新加载页面。
- history原理: 利用H5的 history中新增的两个API pushState() 和 replaceState() 和一个事件onpopstate监听URL变化
- history模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中。
- 利用了HTML5 History Interface 中新增的pushState()和replaceState()方法。
2 父子组件传值 √
3 性能优化指标 ***
4 keep-alive √
5 跨域 √
6 http缓存 √
7 盒模型 √
使用缓存 ***
DNS 查询 ***
8 等比例矩形 css实现宽高等比例自适应矩形
方案: 使用padding-top/bottom和margin-top/bottom 都是相对于父元素来计算
- 第一版: 可以实现效果,但是此时容器的height为0,里面的子元素不能设置高度
<style>
.scale {
width: 100%;
height: 0;
padding-bottom: 50%;
background-color: red;
}
</style>
<body>
<div class="scale"></div>
</body>
- 第二版: 使用absolute 子元素可以设置高度 但是不能设置比例
<style>
.scale {
width: 100%;
padding-bottom: 50%;
height: 0;
position: relative;
}
.item {
width: 100%;
height: 100%;
background-color: aquamarine;
position: absolute;
}
</style>
<body>
<div class="scale">
<div class="item">
容器
</div>
</div>
</body>
- 第三版 希望可以设置比例
上面这个只能设置h:w = 2:1,当我们需要其他比例的时候,而且1这个宽度如果不是100%
- 之前已经在外面套了一层父元素,解决子元素设置宽高的问题
- 再套一层父元素,由这个父元素去控制这个宽度
<style>
.box {
width: 80%;
}
.scale {
width: 100%;
padding-bottom: 50%;
height: 0;
position: relative;
}
.item {
width: 100%;
height: 100%;
background-color: aquamarine;
position: absolute;
}
</style>
<body>
<div class="box">
<div class="scale">
<div class="item">
item
</div>
</div>
</div>
</body>
9 取url 参数 新增 修改
实现一个 modifyUrl 方法,能够新增、修改 url 的查询参数
const url = 'https://www.example.com?keyword=hi'
modifyUrl(url, {
keyword: '你好',
name: 'tom',
})
function modifyUrl (name,value) {
var url = 'https://www.example.com?keyword=hi&jing=123'; // 获取当前页面的url
var newUrl = ""; // 设置新的url
// 使用正则
var reg = new RegExp("(^|)" + name + "=([^&]*)(|$)");
var tmp = name + "=" + value;
console.log(url.match(reg),'1')
/**
* [
'jing=123',
'',
'123',
'',
index: 35,
input: 'https://www.example.com?keyword=hi&jing=123',
groups: undefined
]
*/
if (url.match(reg) != null) {
newUrl = url.replace(eval(reg), tmp); // 有这个值name,就替换
} else {
if (url.match("[\?]")) { // 没这个值name,就添加
newUrl = url + "&" + tmp;
} else {
newUrl = url + "?" + tmp;
}
}
return newUrl;
}
console.log(modifyUrl('jing',90)) // https://www.example.com?keyword=hi&jing=90
console.log(modifyUrl('haozi',00)) // https://www.example.com?keyword=hi&jing=123&haozi=0
10 实现一个方法,接收多个数组,输出合并后数组,结果可以控制按升序还是降序输出
const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
const arr3 = [6, 7, 8]
mergeArr('asc', arr1, arr2, arr3); // [0, 1, 2, 3, 4, 5, 6, 7, 8]
mergeArr('desc', arr1, arr2, arr3); // [8, 7, 6, 5, 4, 3, 2, 1, 0]
mergeArr('asc', arr1)
function mergeArr(sc, arr1, arr2, arr3) {
let len = arguments.length
let res = []
for (let i = 1;i < len;i++) {
res = res.concat(arguments[i])
}
res.sort((a,b) => {
if (sc === 'asc') {
return a-b
} else {
return b-a
}
})
return res;
}
console.log(mergeArr('asc',[1,2],[9,8],[3,7])) // [ 1, 2, 3, 7, 8, 9 ]
console.log(mergeArr('desc',[1,2],[9,8],[3,7])) // [ 9, 8, 7, 3, 2, 1 ]
11 事件循环
console.log(1); // 同步任务1 √
setTimeout(function () { console.log(2); }, 0); // 宏任务1
async function foo() {
console.log(3); // 3 √
await bar();
console.log(4);
}
function bar() {
console.log(5); // √
}
new Promise(resolve => {
foo(); // 同步任务2
resolve(); // 微任务1
}).then(() => {
console.log(6);
})
console.log(7); // 同步任务
// 13574 62
async/await 执行顺序
内部如何执行?
- async/await 是一种编写异步代码的新方法,之前异步代码的方案是回调和promise
- async/await 是建立在promise的基础上的
- async/await 像promise一样,是非阻塞的
- async/await 让异步代码,表现起来更像同步代码
- 首先是async如何处理返回值
有返回值:
async function tesAsync() {
return 'hello async'
}
let result = tesAsync();
console.log(result) // Promise { 'hello async' }
//如果async里面有一个return ,那么会把这个量通过Promise.resolve()封装成Promise对象
没有返回值:
async function tesAsync1() {
console.log('hello async')
}
let result1 = tesAsync1()
console.log(result1)
// hello async
//Promise { undefined }
- await 做了什么处理
await 的意思就是等待,await等待的就是一个表达式,这个表达式的返回值可以是一个promise对象,也可以是其他值
-
很多人以为await会一直等待之后的表达式执行完之后才会继续执行后面的代码,实际上await是一个让出线程的标志。
-
await后面的函数会先执行一遍,然后就会跳出整个async函数来执行后面js栈(后面会详述)的代码
。 -
等本轮事件循环执行完了之后
又会跳回到async函数中等待await后面表达式的返回值
-
如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise放入promise队列(Promise的Job Queue)
- async/await 执行顺序
function testSometing() {
console.log("执行testSometing");
return "testSometing";
}
async function testAsync() {
console.log("执行testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const v1 = await testSometing(); // 关键点1
console.log(v1);
const v2 = await testAsync(); // 关键点2
console.log(v2);
console.log(v1, v2);
}
test();
var promise = new Promise((resolve)=> {
console.log("promise start..");
resolve("promise");
});//关键点3
promise.then((val)=> console.log(val));
console.log("test end...")
// test start...
// 执行testSometing
// promise start..
// test end...
// testSometing
// 执行testAsync
// promise
// hello async
// testSometing hello async
- 当test函数执行到
const v1 = await testSometing();
的时候,会先执行testSometing这个函数打印出“执行testSometing”的字符串,然后因为await会让出线程就会区执行后面的
var promise = new Promise((resolve)=> { console.log("promise
start.."); resolve("promise");});
- 然后打印出“promise start…”接下来会
把返回的这promise放入promise队列(Promise的Job Queue)
,继续执行打印“test end…”, - 等本轮事件循环执行结束后,又会跳回到async函数中(test函数),等待之前await 后面表达式的返回值,因为testSometing 不是async函数,所以返回的是一个字符串“testSometing”
- test函数继续执行,执行到
const v2 = await testAsync();
和之前一样又会跳出test函数,执行后续代码, - 此时事件循环就到了promise的队列,执行promise.then((val)=> console.log(val));then后面的语句,
- 之后和前面一样又跳回到test函数继续执行。
检测 async 执行
async function testSometing() {
console.log("执行testSometing");
return "testSometing";
}
async function testAsync() {
console.log("执行testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const v1 = await testSometing(); // 关键点1
console.log(v1);
const v2 = await testAsync(); // 关键点2
console.log(v2);
console.log(v1, v2);
}
test();
var promise = new Promise((resolve)=> {
console.log("promise start..");
resolve("promise");
});//关键点3
promise.then((val)=> console.log(val));
console.log("test end...")
// test start...
// 执行testSometing
// promise start..
// test end...
// promise
// testSometing
// 执行testAsync
// hello async
// testSometing hello async
promise.then((val)=> console.log(val));
先与console.log(v1)
;执行了,
- 现在
testSometing函数加了async
,返回的是一个Promise对象要要等它resolve, - 将当前Promise推入队列,所以会继续跳出test函数执行后续代码。
- 之后就开始执行promise的任务队列了,
- 先执行了promise.then((val)=> console.log(val))
- 因为这个Promise对象先推入队列;
12 原型链+this
this.a = 'byte';
function A() {
this.a = '123';
}
A.prototype.a = 'b';
A.prototype.log = function() {
console.log(this.a + 1);
}
window.a = 'dance';
var o = new A();
var log = o.log;
console.log(o,'0')
o.log();
console.log(log)
// ƒ () {
// console.log(this.a + 1);
//}
log();
// A {a: '123'} '0'
// 1231
//dance1
13 var let √
var let
function sayHi() {
console.log(name);
console.log(age);
var name = 'Tom';
let age = 21;
}
sayHi()