【web高级进阶之JS】css、js规范+新增数据类型+堆栈溢出+GC垃圾回收
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
【web高级进阶之JS】css、js规范+新增数据类型+堆栈溢出+GC垃圾回收
css、js规范
前端开发团队遵循和约定的代码书写规范意在提高代码的规范性和可维护性提高团队合作效率输出高质量的代码。
团队新规范可以参考https://blog.51cto.com/u_15291238/2980982
一、js 规范
1、文件、资源命名
- 请确保文件命名总是以字母开头而不是数字禁止使用中文命名绝对不要在对象名的字符之间留空格
- 在web项目中所有的文件名应该都遵循同一命名规定。以可读性而言减号
-
是用来分割文件名的不二之选。 - 资源的字母名称必须全为小写这是因为在某些对大小写字母敏感的操作系统例如Linux中当文件通过工具压缩混淆后或者人为修改后大小写不同而导致引用文件不同的错误很难被发现。
不推荐
MyScript.js
myCamelCaseName.css
i_love_underscores.html
1001-scripts.js
my-file-min.css
推荐
My-script.js
my-camel-case-name.css
i-love-underscores.html
thousand-and-one-scripts.js
my-file.min.css
2、文本缩进
一次缩进两个空格
3、注释
写注释一定要注意不要写你的代码都干了些什么而要写你的代码为什么要这样写背后的考量是什么当然那也可以加入所思考问题或是解决方案的链接地址。
不推荐
推荐
4、文件引用加载
- 样式文件
<link rel="stylesheet" href="style/xxx.css" >
- js脚本文件
<script src="script/xxx.js" ></script>
所有浏览器中推荐
省略样式表与脚本上的
type
属性。鉴于HTML5中以上两者默认的type值就是text/css
和text/javascript
所以type属性一般是可以忽略掉的。甚至在老旧版本的浏览器中这么做也是安全可靠的。
不推荐
推荐
5、html引号
虽然双引号和单引号都可以统一都使用双引号“”而不是单引号‘’
不推荐
<div class='news-articles'></div>
推荐
<div class="news-articles"></div>
6、严格模式
ECMAScript5
严格模式可在整个脚本或独个方法内被激活。它对应不同的javascript语境或做出更加严格的错误检查。严格模式也确保了javascript代码更加健壮运行的也更加快速。- 严格模式会阻止使用在未来很可能被引入的预留关键字。
- 你应该在你的脚本中启用严格模式避免在你的脚本第一行使用它而导致你的所有脚本都启动了严格模式这有可能会引发一些第三方类库的问题。
不推荐
推荐
7、变量声明
防止全局污染
不推荐
x = 1;
y = 2;
推荐
var x = 1,
y = 2;
8、提升声明
- 把风险将到最低我们应该手动显示声明变量与方法。也就是说所有变量以及方法应当定义在
function
内的首行。 - 只用一个
var
关键字声明多个变量用逗号隔开。
不推荐
推荐
9、变量判断
不推荐
if(!x){
if(!y){
x = 1;
}else{
x = y;
}
}
推荐
x = x || y || 1
10、字符串定义
统一使用单引号‘’不使用双引号“”
var msg = 'This is some HTML, <div class="masks-sense"></div>';
11、if的判断
用 三元操作符分配或返回语句
在比较简单的情况下使用避免在复杂的情况下使用
不推荐
if(x == 10){
return 'valid'
}else{
return 'invalid'
}
推荐
return x === 10 ? 'valid' : 'invalid';
二、css书写规范
1、css选择器
层级关系严谨一些准确的选到要控制的标签
不推荐
.content .title{
font-size: 2rem;
}
推荐
2、使用css缩写属性
使用CSS缩写属性 比如padding:0 10px 5px 5px等等这样精简代码同时又能提高用户的阅读体验。
不推荐
推荐
3、属性值是0的省略单位
省略 “0” 值之后的单位。不要在0值后面使用单位除非有值。
4、声明顺序
这是一个选择器内书写CSS属性顺序的大致轮廓。这是为了保证更好的可读性和可扫描重要。
作为最佳实践我们应该遵循以下顺序应该按照下表的顺序
属性 | 属性值 |
---|---|
结构性属性 | 1. display 2. position, left, top, right. 3. overflow, float, clear. 4.margin, padding |
表现性属性 | 1. background, border. 2. font, text |
不推荐
推荐
5、CSS优先级
css优先级四大原则
原则一继承不如指定
如果某样式是继承来的永远不如具体指定的优先级高。
例子1
<style type=”text/css”>
*{font-size:20px}
.class3{ font-size: 12px; }
</style>
<span class="class3">我是多大字号</span>
运行结果class3{ font-size: 12px; }
原则二#ID >.class >标签选择符
例子
<style type=”text/css”>
#id3 { font-size: 25px; }
.class3{ font-size: 18px; }
span{font-size:12px}
</style>
<span id="id3" class="class3">我是多大字号</span>
运行结果#id3 { font-size: 25px; }
原则三越具体越强大
当对某个元素的CSS选择符样式定义的越具体层级越明确该定义的优先级就越高。
<style type="text/css">
.class1 .class2 .class3{font-size:25px;}
.class2 .class3{font-size:18px}
.class3 { font-size: 12px; }
</style>
<div class=”class1″>
<p class=”class2″>
<span class=”class3″>我是多大字号</span>
</p>
</div>
运行结果.class1 .class2 .class3{font-size: 25px;}
原则四标签#id >#id 标签.class >.class
<style type=”text/css”>
span#id3{font-size:18px}
#id3{font-size:12px}
span.class3{font-size:18px}
.class3{font-size:12px}
</style>
<span id=”id3″>我是多大字号</span>
<spanclass=”class3″>我是多大字号</span>
运行结果span#id3{font-size:18px} | span.class3{fontsize:18px}
6、常用命名
(1)页面结构
容器: container
页头header
内容content/container
页面主体main
页尾footer
导航nav
侧栏sidebar
栏目column
页面外围控制整体布局宽度wrapper
左右中left right center
(2)导航
导航nav
主导航mainbav
子导航subnav
顶导航topnav
边导航sidebar
左导航leftsidebar
右导航rightsidebar
菜单menu
子菜单submenu
标题: title
摘要:summary
(3)功能
标志logo
广告banner
登陆login
登录条loginbar
注册regsiter
搜索search
功能区shop
标题title
加入joinus
状态status
按钮btn
滚动scroll
标签页tab
文章列表list
提示信息msg
当前的:current
小技巧tips
图标: icon
注释note
指南guild
服务service
热点hot
新闻news
下载download
投票vote
合作伙伴partner
友情链接link
版权copyright
7、CSS各属性的排列顺序不做硬性要求
- Positioning定位如positiontopz-index
- Box model盒模型如displaybox-sizingwidthborder
- Typographic排版如fontline-heighttext-align
- Visual视觉如backgroundcolor,opacity
- Other其他如cursor
1、 由于定位positioning可以从正常的文档流中移除元素并且还能覆盖盒模型box model相关的样式因此排在首位。
2、 盒模型决定了组件的尺寸和位置因此排在第二位。
3、 其他属性只是影响组件的内部inside或者是不影响前两组属性因此排在后面。
8、声明结束
为了保证一致性和可扩展性每个声明应该用分号结束每个声明换行。
9、属性名结束
属性名的冒号后使用一个空格。出于一致性的原因属性和值但属性和冒号之没有空格的之间始终使用一个空格。
10、选择器和声明分离
每个选择器和属性声明总是使用新的一行。
数据类型
1、基本数据类型
Number
、String
、Boolean
、undefined
、Null
、Symbol
、BigInt
- 值
null
特指对象的值未设置。他是JavaScript基本类型之一在布尔运算中被认为是false
类型判断 typeof
//5种数据类型
var num = 1;
var str = "字符串";
var bool = true;
var und = undefined;
var nul = null;
// console.log(num, str, bool, und, nul);
console.log(typeof num);
console.log(typeof str);
console.log(typeof bool);
console.log(typeof und);
console.log(typeof nul);
// [Null] [结果是 object 就是一个历史错误bug](可以参考mdn https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/typeof#typeof_null)
// null 代表 【对象】的值未设置
// null是指对象未被设置undefined是指所有变量声明没被赋值
2、新增的基本数据类型
Symbol
- symbol值一直都是唯一的一个symbol值能作为
对象属性的标识符
即key值
// ES6 Symbol 每次都是新的
var smb0 = Symbol("abc"); // 唯一的看起来像abc的标识
var smb1 = Symbol("abc");
console.log(smb0); // Symbol(abc) 唯一
console.log(smb1); // Symbol(abc) 唯一
console.log(smb0 === smb1); // false 不会类型转换的全等对比对象的引用是否相等如果相等一定是同一个值
// 自己理解提供了Sybmol的注册池注册之后相同标识会从池子里取出来不会再次创建
// Symbol.for(key) 方法会根据给定的键 key来从运行时的 symbol 注册表中找到对应的 symbol如果找到了则返回它否则新建一个与该键关联的 symbol并放入全局 symbol 注册表中。
var smb2 = Symbol.for("xyz"); // 对全局进行注册并保存
var smb3 = Symbol.for("xyz"); // 从全局注册池中获取
console.log(smb2); // symbol(xyz)
console.log(smb3); // symbol(xyz)
console.log(smb2 === smb3); // true
- 避免被重复的算法所覆盖对象的key场景可以参考计算id
Object.getOwmPropertySymbols
可以迭代对象上的该属性链接
// Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性的数组。
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");
obj[a] = "localSymbol"; // obj[Symbol(a)] = "localSymbol"
obj[b] = "globalSymbol"; // obj[Symbol(b)] = "globalSymbol"
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(obj) // {c: 'c', Symbol(a): 'localSymbol', Symbol(b): 'globalSymbol'}
console.log(objectSymbols.length); // 2
console.log(objectSymbols) // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]) // Symbol(a)
console.log(typeof objectSymbols[0]); // symbol
BIgInt
- 它提供了一种方法来表示
2^53 - 1
的整数。这原本是JavaScript中可以使用Number
表示最大的数字。BigInt
可以表示任意大整数。
// - 使用Number
let max = Number.MAX_SAFE_INTEGER // 最大安全整数
console.log(max); // 9007199254740991
let max1 = max + 1 // 9007199254740992
let max2 = max + 2 // 9007199254740992
console.log(max1 === max2); // true :因为 超过阈值计算错误
// - 使用BigInt
// 和Symbol一样不能被new
// 数字n => BigInt字面量声明方式
let maxx = BigInt(Number.MAX_SAFE_INTEGER);
// let maxx1 = maxx + 1; // 会报错Cannot mix BigInt and other types
let maxx1 = maxx + 1n; // 9007199254740992n
let maxx2 = maxx + BigInt(2); // 9007199254740993n
console.log("============重点看下面========");
console.log(maxx1 === maxx2); // false : 超过阈值也可以正确计算
- 由于IE的支持不太好并且当时用BigInt时带小数点的运算会被取整所以实际开发中建议大家使用第三方库来处理
- 官方网站https://github.com/GoogleChromeLabs/jsbi
内存泄漏
想要更深入理解堆和栈的话可以看我这篇文章带你认识理解JS内存机制、数据类型、 事件循环 Event Loop
1、栈内存溢出
function fn1(){
// 栈底
return fn1(); // 压入相对栈底 - 1
// 弹出之后
}
fn()
2、堆内存溢出
let arr = []
// 比较好做类型追溯
function MyObject(){}
while (true){
arr.push(new MyObject()) // 每一次执行都是内存泄漏
}
验证的话浏览器只会崩溃node端会报错
3、内存溢出优化
- map内存溢出优化
a. 内存溢出代码
// 内存溢出代码
// map 和 对象的感觉是类似的 结构差不多 key value
var map = new Map()
var b = new Object()
map.set(b,new Array(1024 * 1024 * 5)) // 开辟内存5M
b. map内存性能优化
// 将key置为null 让其等待垃圾回收
b = null; // 并不是说这个key为null map的value就会释放这取决于map他是否对value有着【强引用】
map = null; // 释放了map,释放了b,才释放了value
优化结束GC垃圾回收之后结果为
- WeakMap内存溢出优化
a. 内存溢出代码
// 内存溢出代码
var wmap = new WeakMap();
var b = new Object(); // map的key
wmap.set(b,new Array(1024 * 1024 * 5) ); // 5M
b. WeakMap内存性能优化
- WeakMap内部使用的是弱引用(虚引用):
- 当其key为null时可以让垃圾回收自动销毁value
// WeakMap和Map一个玩法
b = null;
优化结束垃圾回收之后结果为
Map和WeakMap的区别就在于
WeakMap是虚引用key清空后value的内存会释放
源码
https://github.com/zlzss/WebAdvancedStage_JS
结束
总结不易希望可以收到大家的一键三连欢迎各位评论区提建议