概述
块级作用域
匿名立即执行函数表达式(匿名 IIFE)不再需要
let,const 不会变量提升,不会泄露全局变量例如for(var i = 0, i<n,i++){};
ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域
function f() {console.log('out');}
(function(){
if(false){function f() {console.log('in');}}
f();//f is not a function;
}());
函数声明语句会变量提升而且是全局变量
{
let a = 'secret';
function f() {
return a;
}
};
f(); // secret
解决办法使用函数表达式
function f() {console.log(1);};
{
let a = 'secret';
let f = function () {
return a;
}
};
f(); // 1
暂时性死区
console.log(a); //Uncaught ReferenceError: a is not defined
let a;
typeof b; //Uncaught ReferenceError: b is not defined
let b;
在此之前typeof
运算符是百分之百安全的,永远不会报错;所以变量要声明后使用
function f(x=y,y=0){console.log(x,y);}
f(); //Uncaught ReferenceError: Cannot access 'y' before initialization
//特殊情况也会存在
变量不允许重复声明
const 声明后必须初始化,基础数据类型存在栈内所以不能修改;复合类型栈内存的是指针,
指针不变数据结构是可变的。
Object.freeze();递归解决复合类型数据不可变问题;
import,class,let,const 新增四种变量声明
顶层对象的属性与全局变量挂钩,在编译时没法报出变量未声明的错,很容易不知不觉中创建全局变量,顶层对象的属性都是可读写的不利于模块化编程。Window有实体含义是浏览器窗口对象,顶层对象也是有实体含义的对象。es6解决了这一问题。
globalThis 对象
浏览器里顶层对象是Window,Node是global,Web worker 是self;
严格模式下 this 返回的是undefined;new Function('return this')() 总是返回的是顶层对象;
如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么eval
、new Function
这些方法都可能无法使用。
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
字符的 Unicode 表示法
"u0061" // a
u0061 = 1 // a = 1
bu0061 = 2 // ba = 2
'z' === 'z' // true
'172' === 'z' // true
//172 八进制 ascii , 122 十进制
'x7A' === 'z' // true
//172 十六进制 ascii z
'u007A' === 'z' // true
//Unicode编码 'u0000'到'u007F'对应全部128个ACSII字符
'u{7A}' === 'z' // true
//将码点放入大括号,就能正确解读该字符
字符串的遍历器接口
字符串可以被for...of
循环遍历
let text = String.fromCodePoint(0x20BB7);
for (let i = 0; i < text.length; i++) {
console.log(text[i]);
}
// " "
// " "
for (let i of text) {
console.log(i);
}
// "????"
上面代码中,字符串text
只有一个字符,但是for
循环会认为它包含两个字符(都不可打印),而for...of
循环会正确识别出这一个字符
直接输入 U+2028 和 U+2029
JavaScript 规定有5个字符,不能在字符串里面直接使用,只能使用转义形式
- U+005C:反斜杠(reverse solidus)
- U+000D:回车(carriage return)
- U+2028:行分隔符(line separator)
- U+2029:段分隔符(paragraph separator)
- U+000A:换行符(line feed)
JSON.stringify() 的改造
JSON.stringify('ud834udf06')
//'"????"'
JSON.stringify('u{D834}') // ""\uD834""
JSON.stringify('uDF06uD834') // ""\udf06\ud834""
ES2019 改变了JSON.stringify()
的行为。如果遇到0xD800
到0xDFFF
之间的单个码点,或者不存在的配对形式,它会返回转义字符串,留给应用自己决定下一步的处理。
模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量
// 字符串中嵌入变量
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性能调用函数
大括号中是一个对象,将默认调用对象的toString
方法。
标签模板
let a = 5;
let b = 10;
function tag(s, v1, v2) {
console.log(s[0]);
console.log(s[1]);
console.log(s[2]);
console.log(v1);
console.log(v2);
return "OK";
}
tag`Hello ${ a + b } world ${ a * b}`;
// tag(['Hello ', ' world ', ''], 15, 50) // 等同于
// "Hello "
// " world "
// ""
// 15
// 50
// "OK"
tag
函数所有参数的实际值如下。
- 第一个参数:
['Hello ', ' world ', '']
- 第二个参数: 15
- 第三个参数:50
“标签模板”的一个重要应用,就是过滤 HTML 字符串,防止用户输入恶意内容。
标签模板的另一个应用,就是多语言转换(国际化处理)。
你甚至可以使用标签模板,在 JavaScript 语言之中嵌入其他语言。
function latex(strings) {
// ...
}
let doument = latex`
newcommand{fun}{textbf{Fun!}} // 正常工作
newcommand{unicode}{textbf{Unicode!}} // 报错
newcommand{xerxes}{textbf{King!}} // 报错
Breve over the h goes u{h}ere // 报错
` // undefined
为了解决这个问题,ES2018 放松了对标签模板里面的字符串转义的限制。如果遇到不合法的字符串转义,就返回undefined
,而不是报错,并且从raw
属性上面可以得到原始字符串。
这种对字符串转义的放松,只在标签模板解析字符串时生效,不是标签模板的场合,依然会报错。
let bad = `bad escape sequence: unicode`; // 报错
Uncaught SyntaxError: Invalid Unicode escape sequence
最后
以上就是悦耳香菇为你收集整理的es6 let const 字符串的扩展globalThis 对象的全部内容,希望文章能够帮你解决es6 let const 字符串的扩展globalThis 对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复