搭错车的小火柴

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

零碎的知识点……

👉🏻  腾讯js安全指南

简洁版js运行机制

 

1.空值合并运算符 ??(Nullish coalescing operator)和 逻辑空值赋值运算符 ??=

const foo = null ?? 'default string';
a = 1;
b=null;
b ?? a; // 1
b ??= a; // 1
a = 2;
b ??= a; // 1

2.js中的假值有哪些?

[0, '', NaN, null, undefined]

3.javascript和native通信的场景 

 4.javascript的数组索引取值是怎么进行的?

可以将数组的索引用引号引起来,比如 years[2] 可以写成 years['2']。 years[2] 中的 2 会被 JavaScript 解释器通过调用 toString 隐式转换成字符串,然后取值。

5.javascript执行上下文和执行栈

https://mp.weixin.qq.com/s/3fW_OvnyX-uk_9NfbJKcDw
三种js上下文:全局执行上下文、函数执行上下文(包括arguments)、eval执行上下文

执行上下文的生命周期:创建阶段、执行阶段、回收阶段
在创建阶段,先创建变量对象,再创建作用域链(scope chain),当作用域链开始解析对象时,先从代码最内层嵌套开始,向上查找变量对象,最后确定this指向。
在执行阶段,变量赋值、代码执行。
在回收阶段,执行上下文出栈,等待虚拟机回收执行上下文。

变量声明提升:即使变量在被声明之前使用,也不会报错,此时变量值是undefined,提升到上下文头部。(变量提升作为不合理的地方在ES6中已经解决了,函数提升还存在

函数声明提升:函数定义可以直接声明function a或者函数表达式声明 var a = function。

函数与变量同名时:函数优先级高,变量会被覆盖,但是可以可以重新赋值,从上到下执行。

this的值是在执行阶段的时候才能确认,定义的时候不能确认。
改变this指向的五种方法:fn.call 、fn.apply 、fn.bind、  with 、箭头函数, 都可以。

执行上下文栈:管理执行上下文。js引擎通过上下文栈来存储函数,遵循先进后出,所以window是最后一个出栈的。js是单线程,所有的上下文都要排队顺序执行。内建的异常机制都是沿着函数调用栈的函数调用逆向搜索,直到遇到异常处理代码为止。

6.eval(不怎么用,一直记不住,哈哈哈)

eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。

console.log(eval(“2+2”)) // 4

7.with语句

扩展一个语句的作用域链。

 

  

 8.console.time 计时器 测试环境评估性能

console.time("answer time");
alert("Click to continue");
console.timeLog("answer time");
alert("Do a bunch of other stuff...");
console.timeEnd("answer time");

9.polyfill 和 babel的区别

将新 API 转换为旧浏览器可以理解的代码。

Babel是转换新语法,polyfill是转换新的api。那哪些是新语法,那些是新的api呢?
举个例子:
  新的语法:箭头函数、es6的class、let symbol声明
  新的api:Array.of, Array.from、promise/map/set/include、generator、async函数

 10. JIT & AOT

JIT(Just-in-time:动态编译),AOT(Ahead Of Time:运行前编译 || 构建时编译)

https://juejin.im/entry/5c9455845188252d93207e66

11.undefine 和 null 相等么?双等、三等、Object.is()

undefined == null; // true
undefined === null; // false 

 抽象相等比较(==)、严格相等比较(===)、Object.is()的差别:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness

在比较两件事情时,双等号将执行类型转换; 三等号将进行相同的比较,而不进行类型转换 (如果类型不同, 只是总会返回 false );  而Object.is的行为方式与三等号相同,但是对于NaN和-0和+0进行特殊处理,所以最后两个不相同,而Object.is(NaN,NaN)将为 true。(通常使用双等号或三等号将NaN与NaN进行比较,结果为false,因为IEEE 754如是说.) 请注意,所有这些之间的区别都与其处理原语有关; 这三个运算符的原语中,没有一个会比较两个变量是否结构上概念类似。对于任意两个不同的非原始对象,即便他们有相同的结构, 以上三个运算符都会计算得到 false 。

NaN == NaN; // false
NaN === NaN; // false
0 == -0; // true
0 == +0; // true
0 === +0; // true
0 === -0; // true
Object.is(NaN,NaN); // true

12.获取object的key的三种方式

可枚举属性

// 给 object1 赋值
const object1 = {};
Object.defineProperty(object1, 'property1', {
  value: 2,
  writable: false,
  enumerable:true,
});
Object.defineProperty(object1, 'property2', {
  value: 1,
  writable: false,
  enumerable:false,
});

object1[Symbol.for('meteor')] = 2;

// 获取keys
console.log(Object.keys(object1)); // ["property1"]
console.log(Object.getOwnPropertyNames(object1)); // ["property1", "property2"]
console.log(lect.ownKeys(object1)); // ["property1", "property2", Symbol(meteor)]

13.new 操作符

// todo new的时候发生了什么?constructor 是什么?
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new
a= new String('0');
b='0';

a == b; // true
a === b; // false

14.void 0

void 0 === undefined; // true

15.变量名和函数名重名

 

变量声明和函数声明都会置顶,变量和赋值语句一起书写,在js引擎解析时,会将其拆成声明和赋值2部分,声明置顶,赋值保留在原来位置,声明过的变量不会重复声明,等价于:

var a; //函数声明
var a; //变量声明(实际上这里不会重复声明了)
a = function(){ console.log(a); }; //函数赋值
a = 100;//变量赋值(给a重新赋值了)
a()//a is not a function

16.proxy代理

为了防止某些属性或者function不存在的时候,报错,所以给target加了一层代理
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

let target = {
    a:() => {
        return 9;
    }
};
let p = new Proxy(target, {
    get: function(obj, prop) {
        return prop in obj ? obj[prop] : 37;
    }
});
p.a(); // 9
p.b; // 37

17.var有变量提升,let const有么

https://stackoverflow.com/questions/31219420/are-variables-declared-with-let-or-const-hoisted

结果:有变量提升,但是没有初始化。

18.js文档化注释

https://github.com/fex-team/styleguide/blob/master/javascript.md#243-%E6%96%87%E6%A1%A3%E5%8C%96%E6%B3%A8%E9%87%8A

百度fex团队的js编码规范,里面涉及文档化注释的规范。

/**
  * @author zhangsan
  * @file describe the file
  * @namespace Kwai
  * @class B
  * @extends A
  * @type 类型描述
  * @private  可访问性标记
  * @return {string} 返回值描述
  * @param propertyKey
  * @param params 
  */

19.装饰器

装饰器可以写在类和类方法的定义前面:https://es6.ruanyifeng.com/#docs/decorator

装饰类的时候:第一个参数target是类本身,可以给类增加静态的属性,实例属性,function等……也算是一种mixin或者proxy???。

装饰functionA的时候:装饰器第一个参数是类的原型对象,上例是Person.prototype,装饰器的本意是要“装饰”类的实例。第二个参数是所要装饰的属性名,也就是被修饰的functionA名称,第三个参数是该function属性的描述对象descriptor{value, configurable, writable, enumerable},value有时候是个function或者实例。方法的修饰,target 是 Class 的 prototype, 并不是实例。这个时候实例还未创建出来。

装饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。这意味着,装饰器能在编译阶段运行代码。也就是说,装饰器本质就是编译时执行的函数。@bable/plugin-transfor-decorators

20.class的static属性

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/static

静态方法调用直接在类上进行,不能在类的实例上调用。静态方法通常用于创建实用程序函数。

静态变量只能被静态方法访问。static变量只能通过static方法修改。

应用场景是什么?全局计数器这种?

21.AOP与OOP的设计模式

22.如何快速确定后端接口是否可用、是否跨域?

1.直接在浏览器控制台用fetch

fetch('http://example.com/movies.json')
  .then(function(response) {
    console.log(response);
  })
  .then(function(myJson) {
    console.log(myJson);
  });

2.直接在浏览器控制台用jquery,和方法1一个道理

var importJs = document.createElement('script');
importJs.setAttribute("type", "text/javascript");
importJs.setAttribute("src", 'https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js');
document.getElementsByTagName("head")[0].appendChild(importJs);
$.post('http://baidu.com', (res) => { console.log(res) });

3.postman

23.前端的引擎:渲染引擎和JS引擎

1、渲染引擎:Chrome/Safari/Opera用的是Webkit引擎,IE用的是Trdent引擎,FireFox用的是Gecko引擎。不同的引擎对同一个样式的实现不一致,就导致浏览器的兼容性问题。 

2、JS引擎:js引擎可以说是js虚拟机,负责解析js代码的解析和执行。通常有以下步骤:

  词法解析:将源代码分解位有意义的分词;

  语法分析:用语法分析器将分词解析成语法树;

  代码生成:生成机器能运行的代码;

  代码执行 不同浏览器的js引擎也各不相同,Chrome用的是V8,FireFox用的是SpiderMonkey,Safari用的是JavaScriptCore,IE用的是Chakra。

 之所以说js是单线程就是因为浏览器运行时只开启一个js解释器,原因是若有两个线程操作DOM,浏览器就晕了。 JavaScript是单线程的,但是浏览器不是单线程的。一些I/O操作,定时器的计时和事件监听是由其他线程完成的。

24.append prepend 、after before的区别

append是在currentNode的childrenNodes的末尾push新node

prepend是在currentNode的childrenNodes的开始push新node

 

before是在currentNode的前面添加新node

after是在currentNode的后面添加新node

 

shift和pop:

shift删除数组第一个元素,pop删除最后一个元素,都会更改数组的长度,返回被删除的元素。

Unshift和push:

Unshift往数组前面开始添加元素,push从数组末尾添加,都会更改数组长度,返回数组的新长度

25.怎么实现一个短链服务?

方法1:自增id, 顺序生成。 存url ,溢出时候, 把最近最小访问的清理出去,就是一个key-value,所以第一个链接可能是 http://a。

26.cookie

如何快速种cookie?

''.split(';').forEach(item => document.cookie = `${item.trim()};path=/;expires=${new Date(2099, 1).toUTCString()}`)

如何获取cookie?

// 第一种,只能获取非secure的全部cookie
document.cookie;

// 第二种,获取特定name的cookie
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}

// 第三种,可以获取chrome 87以上的cookie
cookieStore.getAll();
await cookieStore.get({ name: "pgv_pvid" });

cookieStore的w3c文档草案地址:https://wicg.github.io/cookie-store/#CookieStore 

27.摩斯电码字典

 

 28.toString怎么把AscII码转换成对应的字符?

Object.prototype.toString():方法返回一个表示该对象的字符串;

Number.prototype.toString():方法返回指定 Number 对象的字符串表示形式。

let a=11;
a.toString(36); // "b"

如何使用摩斯电码加密文本?如何加密中文?https://mp.weixin.qq.com/s/DdWzKFh0wwmayuymHsfIEA

29.socket.io调试看数据

localStorage.debug = '*' 

https://blog.csdn.net/gamesdev/article/details/51730997

30.ID生成器:nanoid

31.userAgent解析器:UAparser

32.什么是高阶插件?

把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
http://hcysun.me/2018/01/05/%E6%8E%A2%E7%B4%A2Vue%E9%AB%98%E9%98%B6%E7%BB%84%E4%BB%B6/

33.前端工程化

工程架构角度
前端工程化的几个需要关注的点:
1.持续集成:
  利用gitlab ci代替ksp 和 jenkins
2.架构设计与业务拆分
3.基础平台建设
  利用sentry实现错误监控管理
  利用windows.performance实现性能监控

34.rxJS

在项目里面,用了rxJS之后,理解其是一个js工具。不过声明式编程分风格,的确对我现有编码习惯影响很大。还在持续理解和深入学习中

35.gitlab的webhook的CI/CD集成配置

https://www.jianshu.com/p/00bc0323e83f
可以参照git hooks: https://git-scm.com/docs/githooks
https://git-scm.com/book/zh/v2/自定义-Git-Git-钩子

怎么联合jenkins生成gitWebhook地址:https://www.cnblogs.com/kevingrace/p/6479813.html

gitlab CI : https://segmentfault.com/a/1190000007180257
webhook 文档:https://docs.gitlab.com/ee/user/project/integrations/webhooks.html

36. microtask macrotask

37.mock数据的工具:fakerjs mocker-api

38.nodemon

Hot Module replacement 能够使得应用在运行时,无需开发者重新npm run dev、刷新页面,便能更新更改的模块,并且将效果及时展示出来,主要针对于Src目录下的文件。
但是一旦某个配置文件,如webpack、server、graphql等配置改动时,server是不会自己重新run一次的,必须手动再run一次。Nodemon就可以解决这个问题,在nodemon.json中指定ignore和watch的文件,就可以监听这些变化,一旦这些watch的内容发生变化,nodemon就会自动重启应用。

39.移动端h5调试工具:vconsole vs eruda

40.Metric讲解

metric中文意思是指标,是监控系统中的基本单元,一条metric相当于db表里的一条记录,因为现在大部分metric最终也都是存在某一种db中,所以也只是换了个名字。
一张表有很多字段(column),对应metric中有很多标签(label/tag)。https://blog.csdn.net/xsgnzb/article/details/78776619内存:

mem.memfree.percent:内存剩余的百分比
CPU:
  cpu.idle:CPU空闲百分比
  cpu.iowait:CPU的IO等待的百分比
磁盘:
  disk.io.write_bytes/device=vdb:磁盘的写入速率
  disk.io.read_bytes/device=vdb:磁盘的读取速率
  disk.io.await:每一个IO请求的处理的平均时间(单位是毫秒),这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。
  disk.io.util:IO使用率
网络net
  net.if.in.bytes/iface=eth0 网络上传速率(M/s)
  net.if.in.packets/iface=eth0 网络上传速率(数据包/s)
  net.if.out.bytes/iface=eth0 网络下载速率(M/s)
  net.if.out.packets/iface=eth0 网络下载速率(数据包/s)
  net.if.total.bytes/iface=eth0 网络总传输速率(M/s
  net.if.total.packets/iface=eth0 网络总传输速率(数据包/s)
负载:
  load.15min:15分钟运行进程队列中平均负载
  load.1min:1分钟运行进程队列中平均负载
  load.5min:5分钟运行进程队列中平均负载
解释:
系统平均负载是CPU的Load,它所包含的信息不是CPU的使用率状况,而是在一段时间内CPU正在处理以及等待CPU处理的进程数之和的统计信息,也就是CPU使用队列的长度的统计信息。这个数字越小越好。(建议最大是内核数*0.7)
  df.bytes.free:磁盘可用量
  df.bytes.free.percent:磁盘可用量占总量的百分比
  df.bytes.total:磁盘总大小
  df.bytes.used:磁盘已用大小
  df.bytes.used.percent:磁盘已用大小占总量的百分比(监控这个指标报警)
  df.inodes.total:inode总数
  df.inodes.free:磁盘可用inode数目
  df.inodes.free.percent:可用inode百分比
  df.inodes.used:磁盘已用的inode数据
  df.inodes.used.percent:已用inode百分比(监控这个指标报警)

  disk.io.ios_in_progress:当前正在运行的实际I / O请求数
  disk.io.msec_read:所有读取花费的总计ms数
  disk.io.msec_total:ios_in_progress> = 1的时间量
  disk.io.msec_weighted_total:统计最近的I / O完成时间和积压。
  disk.io.msec_write:所有写入所花费的总时间
  disk.io.read_merged:相邻的读取请求合并在单个req中
  disk.io.read_requests:读取成功完成的总数(汇总)
  disk.io.read_sectors:成功读取的扇区总数
  disk.io.write_merged:相邻的写请求合并在单个请求中
  disk.io.write_requests:成功写入磁盘的总次数
  disk.io.write_sectors:成功写入扇区数的总次数
  disk.io.read_bytes:单位是byte的数字
  disk.io.write_bytes:单位是byte的数字

41.git相关

git用法:
先git clone 项目代码
git pull拉别人代码
git pull origin develop

git pull = git fetch + git merge

git add commit push / 
git push --set-upstream origin haha
提交代码:
git push --set-upstream origin haha/loginfix
git push --set-upstream origin haha/component
git squash(https://blog.csdn.net/xiaozhidexiao/article/details/78509676)
git rebase –i HEAD~X
git reset --soft commitId 
代替git merge 合并主分支:git rebase origin/develop
开始修改commits:  git rebase -i origin/develop
停止rebase: git rebase –abort
继续rebase: git rebase –continue
git commit --amend
https://git-scm.com/book/zh/v1/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E5%86%99%E5%8E%86%E5%8F%B2
git重写历史相关

git hooks: https://www.cnblogs.com/StitchSun/articles/4712287.html

git pull –r === git pull –rebase

git批量删除本地分支,过滤某些分支:
git branch |grep '分支过滤关键字' |xargs git branch –D
git branch | grep -v 'master' | xargs git branch -D
git branch -D `git branch | grep -vE 'master'`  // 删除除master之外的分支 git 强制删除本地所有分支: git branch
| xargs git branch –D 删除本地与远端同步的分支,未同步的commit分支不会删除: git branch | xargs git branch –d 删除本地2017年分支 git branch | grep 2017 | xargs git branch -D

放弃某个文件的修改
git checkout -- [filename]

放弃目前所有修改
git checkout -- .

42.localStorage在无痕模式下的兼容性问题

谷歌浏览器在无痕模式下,一个页面打不开了,查了一下,发现谷歌浏览器的无痕模式下,localStorage是被禁用的

(其实低版本的浏览器也有兼容问题:https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API) 

 那怎么判断浏览器是否处于无痕模式呢?

https://stackoverflow.com/questions/2909367/can-you-determine-if-chrome-is-in-incognito-mode-via-a-script/57438917

 43.document.cookie和Application的cookie拿到的cookie不一样

1.HttpOnly 属性可以阻止通过javascript访问cookie, 从而一定程度上遏制这类攻击。所以拿不到httpOnly属性为true的cookie

2.要获取的cookie的domain和当前页面的domain不一样

 

44.逻辑与 &&

 || 返回的是表达式里面第一个真值或者最后一个假值;

&& 返回的是表达式里面第一个假值或者最后一个真值

 

 

foo() && 1,其中 foo() 运行后打印出了123,但是函数没有return,所以默认 return undefined  。

 

45.跨站和跨域一样么?

不一样,跨站一定跨域,跨域不一定跨站。

参考:https://juejin.cn/post/6926731819903631368

在业务场景上,跨站的问题更多些。

比如 axios 的 withCredentials ,是可以携带跨域的cookie,但是在一些禁止第三方cookie的浏览器上,是还不能携带跨站的cookie的。

举个例子 a.b.com跨域请求e.b.com的接口,可以带上e.b.com的cookie。。但是c.d.com跨站请求e.b.com的接口,在禁用第三方cookie的浏览器里面带不上 e.b.com的cookie的。

 cookie的SameSite:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies

 

 safari跨站种不上cookie的问题,能通过iframe解决么?

1.a.b.com打开一个c.d.com的iframe,iframe里面直接给c.d.com种cookie,safari是种不上的。是的,iframe里面也是种不上的。

关掉safari的“阻止跨站跟踪”就可以种。

 

 2.用户显式的打开一次c.d.com的方法

https://www.xiaoboy.com/topic/safari-iframe-cannot-set-cookie.html

这篇文章写的是用户显式的打开一次c.d.com,a.b.com此时打开c.d.com的iframe,iframe里面可以直接给c.d.com种cookie。

但是本地尝试了一下,给c.d.com set-cookie失败,再次请求c.d.com,request 也带不上任何cookie。

所以我理解要想完成跨站种cookie,只能显示的跳转,在跨站的页面完成操作,再跳回原站。

 

46.浏览器请求的302和ajax的302有什么区别?

参考:https://blog.lishunyang.com/2020/06/redirect.html

1.浏览器直接发起的请求type不是 xhr ,是document等类型。ajax 的 type 就是 xhr。

2.浏览器直接发起的请求,后端返回302,浏览器会自动跳转到302的地址。ajax不会自动跳,会再发起一个请求,如果需要跳转,需要手动 window.location.href = url;

47.清空数组

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/length

 

 

数组长度length 属性不一定表示数组中定义值的个数。了解更多:长度与数值下标属性之间的关系

 

 

 48.浏览器的进程数

chrome是多进程架构

 

可以看到,chrome每个标签页都有自己的进程,这也就是为什么一个tab页面卡死的时候,其他页面还能正常运行的原因,每个tab都是一个沙盒。

浏览器内核是多线程架构,一般包括渲染线程、js线程、定时器线程、event线程、http异步请求线程。

渲染线程和js线程是互斥的,为了防止渲染出现不可预期的结果,同一时间,只能有一个在运作。

 

49. symbol用法和场景

见:https://github.com/Alanrah/learn-point-impl-vue/blob/master/src/views/ts/symbol.ts 

 

50.时间戳

时间戳有10位和13位的,10位的时间戳精确到秒,13位的时间戳精确到毫秒。

 

 https://momentjs.com/docs/#/displaying/format/

 

 

时间表示有两个标准:localtime 和 UTC(Coordinated Universal Time) 。

  • UTC 是与时区无关的全球时间标准。尽管概念上有差别,UTC 和 GMT (格林威治时间) 是一样的。UTC相当于本初子午线(即经度0度)上的平均太阳时
  • localtime 标准则依赖于当前时区。
  • UTC就是0时区的时间,(LocalTime)地方时为本地时间,如北京为早上八点(东八区),UTC时间就为零点

51.下载文件

我们在web端,有点击链接,下载文件的场景。

问题1:有时候会发现,点开某个a标签文件链接(.doc, .pdf, .xls, .zip等) ,浏览器是展示了文件内容,并没有按照预期去下载文件?

问题2:有时候,我们需要改变下载文件的filename,但是设置了download属性,却不生效?

解决1:是因为提供下载服务的接口的content-type不对,具体见:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types#设置正确的mime类型的重要性

需要服务端设置一下content-type:

     const buf = downLoadContent;
        res.set({
            'Content-Type': 'application/octet-stream', // 强制改成二进制文件下载,但是会丢失文件类型信息,所以要结合 content-disposition 的 filename 属性,不然默认是.txt
       'Content-Length': buf.length,
       'content-disposition': `attachment;filename=${encodeURIComponent('预期的名字.后缀')}`, });

解决2:a标签href属性的地址必须是和前端js非跨域的地址,如果引用的是第三方的网站或者说是前后端分离的项目,调用后台的接口,这时download就会不起作用。

具体见: https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a#attr-download

也可以通过自定义下载response类型的方法来解决,比如下载一些文本文件:

function downLoadFileWithName(path: string, fileName: string) {
    const req = new window.XMLHttpRequest();
    req.open('GET', path, true);
    req.responseType = 'blob';
    req.onload = () => { // 请求成功完成时触发, 将请求结果转换为blob,然后赋值给a标签的href
        const url = window.URL.createObjectURL(req.response);
        const a = document.createElement('a');
        a.href = url;
        a.download = fileName;
        a.click();
    };
    req.send();
}

a标签的download属性的name值,优先级小于 content-disposition 设置的 filename;

如果想通过点击链接直接下载图片,也可以将图片内容转换成base64文件,然后赋值给a标签的href,道理是一样的。

 其他类型:

在chrome浏览器上,application/x-apple-diskimage(.dmg),application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(.xlsx),都是可以直接通过a链接下载的。

 更多见: https://mp.weixin.qq.com/s/vZiP2ULrLRtqShDJ9u1n2A

52.降域

 

 document.domain 解析

 常用场景:利用document.domain 实现跨域:前提条件:这两个域名必须属于同一个根域名,协议和端口一致,否则设置 document.domain 不会生效。

Javascript出于对安全性的考虑,禁止跨域操作。developer.mozilla.org 和 mozilla.org 是跨域的,这时候可以设置 developer.mozilla.org 页面的 domain 为 mozilla.org,这样就解决了跨域问题。但是不推荐,还是用 postMessage 安全些。
 

53.preload prefetch

http://www.yaohaixiao.com/blog/preload-key-requests/

 

 示例地址:

二次下载,那预下载就没有意义了。

举个例子,用vue-cli创建的项目,在vue.config.js的设置中,将设置 crossorigin: 'anonymous'  (👉🏻),build 出来的index.html文件中,就会将link和script的crossorigin显式设置为anonymous。

 

 如果不显式设置,结果如下:

 

54. http状态码

 

55.设计原则 SOLID

单一职责原则(SRP:Single Responsibility Principle):一个对象(方法)只做一件事情,把对象划分成较小的粒度,这可以提高对象的可复用性。

开放-封闭原则(OCP:Open Closed Principle):当需要改变一个程序的功能或者给这个程序增加新功 能的时候,可以使用增加代码的方式,但是不允许改动程序的源代码。对扩展开放,对修改封闭。

里氏替换原则(LSP):能够使用父类的地方,一定可以使用其子类,并且预期结果是一致的。

接口隔离原则(ISP:Interface Segregation Principle):不要将一个大而全的接口扔给使用者,而是将每个使用者关注的接口进行隔离。

依赖倒置原则(DIP:Dependence Inversion Principle):使用者依赖一个抽象的服务接口,而不是去依赖一个具体的服务执行者,从依赖具体实现转向到依赖抽象接口,倒置过来。要针对抽象(接口)编程,而不是针对实现细节编程。

 

todo: 前端的加密方式集合

一些相似产品的比较,优缺点发掘,深入使用

 

posted on 2020-11-06 11:50  搭错车的小火柴  阅读(215)  评论(0编辑  收藏  举报