es6学习笔记、知识点总结(附:常考面试题)
记录一些自己在学习es6的心得和笔记。补充一些关于es6的面试题。
1. let
和 const
let
声明的变量只在代码块中有效,块外访问报错!- 经典案例:for循环中用var和let的区别,异步打印i(var情况属于内存泄漏)
- for循环中,let可以覆盖条件中的变量,相当于父子作用域问题
- 没有变量提升,必须先声明后使用,否则报错
- 不论父作用域是否存在x变量,只要子作用域使用了let x ,都必须先定义后使用,否则报错
- 块作用域内重复声明变量,直接报错
面试题
为撒需要快作用域呢?
答案:1.上面讲的for循环内存泄漏;2. 内层变量可能会覆盖外层变量。见下面场景代码
1
2
3
4
5
6
7
8
9
10 var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
- 有了快作用域,不再需要IIFE(立即执行函数表达式(fn(i){})(i)),直接用大括号扩起来即可
- 函数声明语句的行为类似于let,思考一下,联系上面
- 块作用域必须有大括号,否则不是块作用域,类似:省略写法:
if (true) let x = 1
; const
也是只在块作用域内有效cosnt
使得变量指向内存地址不的改动。(ps:简单数据的值就保存在内存地址,引用型在内存地址中保存的是指针)Object.freeze
可以使对象内部属性也不能增删改,!!!!只能冻结一层!下面实现递归可以深层冻结
Object.freeze
实现原理。
1
2
3
4
5 for(let key in obj){
Object.definedProperty(obj,p,{
wwriteable:false
})
}
Object.freeze
实现完全(彻底)冻结原理。(原理这个东西,面试一半会问,真是写代码肯定是越少越好啊)
实际是将对象变得不可扩展,已有属性不可重写,Object.definedProperty()、Object.seal()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 //es5
function littlefreeze(obj){
if(obj instanceof Object){
Object.seal(Object); //不能扩展、删除属性
}
for(let key in obj){
if(obj.hasOwnProperty(p)){
Object.definedProperty(obj,p,{
wwriteable:false
})
}
littlefreeze(obj[key]) // 如果没有这一步周
}
}
//es6
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});
};
- let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性
1 | //在浏览器全局执行 |
2.解构赋值
只有当一个数组成员严格等于
undefined
,默认值才会生效。1
2
3let [x = 1] = [null];
x // null
// null ===undefined return false默认值声明相当于let,如下报错
1
let [x=y,y=1] = []; //error:y is not defined
对象的解构,不是按照顺序,而是按照相同属性名称
let { foo: baz } = { foo: 'aaa', bar: 'bbb' }
- 继承的属性也可以取到
- 已声明的变量,解构赋值要加括号,不论var、let、const
声明语句都不能带圆括号,赋值语句模式不能带括号(理解)
1
2
3
4
5[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确,p是模式,d是变量
//
let [(a)] = [1]; // 错误
let {x: (c)} = {}; // 错误解构用途:赋值、遍历键值对、取值
3.字符串扩展
- unicode 表示法,emmmmm这个用的比较少。
- 模板字符串了解下:
aaaaaa${变量}bbbbb
- 标签模板功能,如下代码:
1
2
3
4
5
6
7
8
9//简单的
alert`123` === alert(123)
//复杂的
let a = 1;
let b = 2;
function shit(str,变量1,变量2,...){log一下}
// 不添加参数,就不接收
一个简单的转译用户提交text的通用函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 function SaferHTML(templateData) {
let s = templateData[0];
for (let i = 1; i < arguments.length; i++) {
let arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// Don't escape special characters in the template.
s += templateData[i];
}
return s;
}
let sender = '<script>alert("abc")</script>'; // 恶意代码
let message = SaferHTML`<p>${sender} has sent you a message.</p>`;
message
// <p><script>alert("abc")</sc
- emmmm涉及到了好多
unicode
,不懂啊,暂时先放过 String.fromCodePoint()
可以识别大于0xFFFF的字符startsWith
,endsWith
,includes
,
上面前两个方法es5写法如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 String.prototype.startWith = function(str){
if(str==null||str==""||this.length==0||str.length>this.length){
return false;
}
if(this.substr(0,str.length == str)){
return true;
}else{
return false
}
return true;
}
String.prototype.endWith = function(str){
if(str==null||str==""||this.length==0||str.length>this.length){
return false;
}
if(this.substring(this.length - str.length) == str){
return true
}else{
return false
}
return true
}