RN学习之ECMAScript6

2019-08-21  本文已影响0人  莫念数不清的心事

了解了JS之后 就要开始ES6的学习了。http://es6.ruanyifeng.com/#docs/let

敲不下去还是看看就完了…… 敲麻烦

在线转换

Babel 提供一个REPL 在线编译器,可以在线将 ES6 代码转为 ES5 代码。转换后的代码,可以直接作为 ES5 代码插入网页运行。
作者写了一个工具ES-Checker,用来检查各种运行环境对 ES6 的支持情况。访问ruanyf.github.io/es-checker,可以看到您的浏览器支持 ES6 的程度。运行下面的命令,可以查看你正在使用的 Node 环境对 ES6 的支持程度。

敲敲更深刻
二、 let和const命令

{
let a = 10;
var b = 1;
}
a // 代码块之外let变量报错 ReferenceError: a is not defined.
b //1

看到了 console.log 依旧不知道什么意思 这篇文章写的好清楚,等什么时候顿悟了再看
https://segmentfault.com/a/1190000012957199

console.error('这里头是提示错误信息文本');


console.error('这里头是提示错误信息文本');

console.warn('这里头是警告信息文本');


console.warn('这里头是警告信息文本');

看不懂接着看吧先
变量提升
var变量可以在声明之前使用,值为undefined。
let改变了这个语法行为,一定要先声明后使用
暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var tmp = 123;

if (true) {
 tmp = 'abc'; // ReferenceError
 let tmp;
}

“暂时性死区”也意味着typeof不再是一个百分之百安全的操作。

typeof x; // ReferenceError
let x;

如果一个变量根本没有被声明,使用typeof反而不会报错。

typeof undeclared_variable // "undefined"
function func(arg) {
  let arg; // 报错
}

function func(arg) {
  {
    let arg; // 不报错
  }
}

总之变量先声明再使用就对了……

其实这些都跟OC一样,一个大括号内不能重复命名,相同的变量名字大括号内优先于大括号外,大括号外头访问到的是大括号外头的那个变量,是访问不到大括号里头的变量的

const PI = 3.1415926;
PI=3;//就会报错

const的作用域与let命令相同:只在声明所在的块级作用域内有效。
本质:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。

const a = [];
a.push('Hello'); // 可执行
a.length = 0;    // 可执行
a = ['Dave'];    // 报错

如果真的想将对象冻结,应该使用Object.freeze方法。

如果真的想将对象冻结,应该使用Object.freeze方法。

const foo = Object.freeze({});

// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;

上面代码中,常量foo指向一个冻结的对象,所以添加新属性不起作用,严格模式时还会报错。

除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  });
};

ES6声明变量的六种方法

ES5只有两种声明变量的方法var和function。
ES6添加了 let、const、import、class

ES6改进这一点,为了兼容性,var命令和function命令声明全局变量,依旧是顶层对象的属性 另一方面 let、const、class不属于顶层对象。ES6开始 全局变量将逐步与顶层对象的属性脱钩

var a = 1;
// 如果在 Node 的 REPL 环境,可以写成 global.a
// 或者采用通用方法,写成 this.a
window.a // 1

let b = 1;
window.b // undefined

上面代码中,全局变量a由var命令声明,所以它是顶层对象的属性;全局变量b由let命令声明,所以它不是顶层对象的属性,返回undefined。let声明的不是全局变量 window这个顶层对象是获取不到的
三、变量的解构赋值

let a = 1;
let b = 2;
let c = 3;

ES6允许写成这样

let [a,b,c] = [1,2,3];

可以从代码中提取值,按照对应位置,对变量赋值。
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋值对应的值,

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

let [foo] = [];
let [bar, foo] = [1];
以上两种情况都属于解构不成功,foo的值都会等于undefined。

不完全解构,右边的值只能能对应上左边一部分,包含,能对上哪个哪个就有值……

let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

如果数组对应的右边值不是可以遍历的解构 那就就报错

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
let{bar,foo} = {foo:"aaa",bar: "bbb"};
foo //"aaa"
bar //"bbb"

let {baz} = { foo:"aaa",bar:"bbb"};
baz //undefined
let {foo:foo}={foo:"aaa"};
let {foo:baz} = {foo:"aaa"}

baz //"aaa"
foo //error:foo is not define

上面代码中,foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo

let {foo:{bar}} = {baz:'baz'};

foo对象有个子对象{bar},foo没有对应的值是undefined,那么bar肯定也就更没有了,对空取值 那就报错了

let _tmp = {baz:'baz'};
_tmp.foo.bar //报错

对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。

let { log, sin, cos } = Math;

数组的对象都有一个length属性,因此还可以对某种对象的属性结构赋值

let {length:len} ='hello';
len // 5
let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
function add ([x,y]){
return x+y;
}

add([1,2]);//3

上面代码中,函数add的参数是个数组,但传入参数在内部就会被解构成变量 x 和 y。

不能使用圆括号的情况
(1)变量声明
(2)函数的参数
(3)赋值语句 ([a])= [5];//报错

可以使用圆括号的情况
赋值语句的非模式部分

[(b)] = [3]; //取得数组第一个成员,跟圆括号无关
({p:(d)}) = {}); //模式是p
[(parseInt.prop)] = [3]; // 
let x = 1;
let y = 2;
[x,y] = [y,x];

(2)从函数返回多个值
将他们放在数组或者对象中返回

//返回一个数组
function example () {
 return [1,2,3];
}

//返回一个对象
function example () {
 return{foo:1,bar:2};
}
let {foo,bar} = example();

(3)函数参数的定义方便将一组参数与变量名对应取来

// 参数是一组有序的值
function f ([ x , y , z]){……}
f([1 , 2 , 3]);
//参数是一组无次序的值
function f ({x , y , z}){……}
f ({z : 3, y : 2 , x = 1});

(4)提取 JSON 数据

let jsonData = {
  id : 42,
  status : "OK",
data : [867,590]; 
};
let {id , status,data:number}  = jsonData;

(5)函数参数的默认值

jQuery.ajax = function( url , {
  async = true,
  beforeSend = function(){},
  cache = true,
  complete = function (){},
  crossDomain = false,
  global = true,
  // more config
} = {}){
  // do stuff
};

指定参数的默认值,就避免了在函数体内部再写 var foo = config.foo || 'default foo';

(6)遍历Map结构 Map 是个键值对的结构 字典??

const map = new Map();
map.set('first','hello');// 添加一对键值对,(key,value)
map.set('second','world');

for (let [key , value] of map){
console.log( key + "is" + value); 
}
// first is hello
// second is world

只想获取键名,或者只想获取键值

// 获取键名
for (let [key]  of map){
}
// 获取键值
for (let [ ,value] of map){
}

(7)输入模块的指定方法

const {sourceMapConsumer,SourceNode } = require("source-map");

四、字符串的扩展

"\u0061" //"a"

但,这种表示法只限于码点在\u0000 ~ \uFFFF之间的字符。超过这个范围,必须用两个双字节的形式表示

"\uD842\uDFB7"  // "𠮷"

"\u20BB7"   //超过了0xFFFF的数值 JS理解成\u20BB+7
//由于\u20BB是个不可打印的字符,所以只会显示一个空格 跟一个7
// 7

ES6对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符

"\u{20BB7}" // "𠮷"
"\u{41}\u{42}\u{43}" //"ABC"
let hello = 123;
hell\u{6F} // 123
'\u{1F680}' === '\uD83D\uDE80'
// true
var s = "𠮷";// 码点为 0x20BB7 UTF-16编码为0xD842 0xDFB7 (十进制为55362 57271  ) 四个字节
s.length // 2
s.charAt(0) // ' '
s.chatAt(1) // ' '
s.charCodeAt(0) //55362
s.charCodeAt(1) //57271 

ES6 提供了codePointAt方法,能够正确处理 4 个字节储存的字符,返回一个字符的码点。

let s = '𠮷a';

s.codePointAt(0) // 134071
s.codePointAt(1) // 57271

s.codePointAt(2) // 97
codePointAt 方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下。
let s = '𠮷a';

s.codePointAt(0).toString(16) // "20bb7"
s.codePointAt(2).toString(16) // "61"

字符串可以被for...of循环遍历。

模板字符串中嵌入变量,需要将变量名写在${}之中。

function fn() {
  return "Hello World";
}

`foo ${fn()} bar`
// foo Hello World bar

如果大括号中的值不是字符串,将按照一般的规则转为字符串。比如,大括号中是一个对象,将默认调用对象的toString方法。

上一篇 下一篇

猜你喜欢

热点阅读