你不知道的 JS

// counter.js
let counter = 10;
export default counter;
// index.js
import myCounter from "./counter";

myCounter += 1;

console.log(myCounter);

引入的模块是 只读 的: 你不能修改引入的模块。只有导出他们的模块才能修改其值。当我们给myCounter增加一个值的时候会抛出一个异常: myCounter是只读的,不能被修改

delete操作符返回一个布尔值: true指删除成功,否则返回false. 但是通过 var, const 或 let 关键字声明的变量无法用 delete 操作符来删除。

name变量由const关键字声明,所以删除不成功:返回 false. 而我们设定age等于21时,我们实际上添加了一个名为age的属性给全局对象。对象中的属性是可以删除的,全局对象也是如此,所以delete age返回true.

2.

var b = 10;
(function b(){
    b = 20;
    console.log(b); 
})();
打印的是 function b(){b=20; console.log(b)};
// 关于作用域 立即执行函数b, 函数变量名称b 的作用域只局限在这个函数内,
// 在非匿名自执行函数中,函数变量为只读状态无法修改;

3 BFC block formatting context

通俗一点来讲,可以把 BFC 理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部

只要元素满足下面任一条件即可触发 BFC 特性:

  • body 根元素
  • 浮动元素:float 除 none 以外的值
  • 绝对定位元素:position (absolute、fixed)
  • display 为 inline-block、table-cells、flex
  • overflow 除了 visible 以外的值 (hidden、auto、scroll)

BFC 特性及应用

  1. 同一个 BFC 下外边距会发生折叠( 比如 Margin 重合会折叠)
  2. BFC 可以包含浮动的元素(它将清除浮动)
  3. BFC 可以阻止元素被浮动元素覆盖 (浮动元素会遮盖普通文挡流, 不会遮盖BFC元素 )

浏览器header 安全 策略

strict-transport-security

link

x-frame-options

已广泛支持的非官方标准

HTTP 响应头是用来给浏览器 指示允许一个页面 可否在 <frame> ,<iframe> , <embed> 或者 <object> 中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免 clickjacking 攻击。

X-Frame-Options: deny 
X-Frame-Options: sameorigin  
X-Frame-Options: allow-from https://example.com/

x-content-type-options

HTTP 消息头相当于一个提示标志,被服务器用来提示客户端一定要遵循在 Content-Type 首部中对 MIME 类型 的设定,而不能对其进行修改。这就禁用了客户端的 MIME 类型嗅探行为,换句话说,也就是意味着网站管理员确定自己的设置没有问题。就是阻止不可执行的 MIME 类型转变为可执行的 MIME 类型

X-Content-Type-Options: nosniff
nosniff
下面两种情况的请求将被阻止:
请求类型是"style" 但是 MIME 类型不是 "text/css",
请求类型是"script" 但是 MIME 类型不是 JavaScript MIME 类型。

X-XSS-Protection

响应头是 Internet Explorer,Chrome 和 Safari 的一个特性,当检测到跨站脚本攻击 (XSS)时,浏览器将停止加载页面。 若网站设置了良好的 Content-Security-Policy 来禁用内联 JavaScript (‘unsafe-inline’),现代浏览器不太需要这些保护, 但其仍然可以为尚不支持 CSP 的旧版浏览器的用户提供保护。

X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>
  • 0禁止XSS过滤。
  • 1启用XSS过滤(通常浏览器是默认的)。 如果检测到跨站脚本攻击,浏览器将清除页面(删除不安全的部分)。
  • 1;mode=block启用XSS过滤。 如果检测到攻击,浏览器将不会清除页面,而是阻止页面加载。
  • 1; report=<reporting-URI>  (Chromium only)启用XSS过滤。 如果检测到跨站脚本攻击,浏览器将清除页面并使用CSP report-uri指令的功能发送违规报告

使用 WithStyles 来扩充你的属性

//不推荐
const styles = (theme: Theme) => createStyles({
  root: { /* ... */ },
  paper: { /* ... */ },
  button: { /* ... */ },
});

interface Props {
  // 未被注入样式的属性
  foo: number;
  bar: boolean;
  // 被注入样式的属性
  classes: {
    root: string;
    paper: string;
    button: string;
  };
}

//推荐:
import { WithStyles, createStyles } from '@material-ui/core';

const styles = (theme: Theme) => createStyles({
  root: { /* ... */ },
  paper: { /* ... */ },
  button: { /* ... */ },
});

interface Props extends WithStyles<typeof styles> {
  foo: number;
  bar: boolean;
}

Decorator

就是把类作为参数 传给 装饰器函数
[cc lang=”js”]
@frozen class Foo {
@configurable(false)
@enumerable(true)
method() {}

@throttle(500)
expensiveMethod() {}
}

//装饰器可以用来装饰整个类

@testable
class MyTestableClass {
// …
}

function testable(target) {
target.isTestable = true;
}

MyTestableClass.isTestable // true
[/cc]

前面的例子是为类添加一个静态属性,如果想添加实例属性,可以通过目标类的prototype对象操作。
[cc lang=”js”]function testable(target) {
target.prototype.isTestable = true;
}

@testable
class MyTestableClass {}

let obj = new MyTestableClass();
obj.isTestable // true[/cc]

[cc lang=”js”]@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}[/cc]

按需加载,异步代码分割

结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

把组件按组分块

有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

js 对象的copy

JSON.parse(JSON.stringify(obj))我们一般用来深拷贝

1、如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象
2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;

3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;

4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null

5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;

6、如果对象中存在循环引用的情况也无法正确实现深拷贝;

MessageChannel copy
[cc lang=”javascript”]
function structuralClone(obj) {
return new Promise(resolve => {
const {port1, port2} = new MessageChannel();
port2.onmessage = ev => resolve(ev.data);
port1.postMessage(obj);
});
}
const obj = /* … */
const clone = await structuralClone(obj);
[/cc]