资讯专栏INFORMATION COLUMN

解析ES6变量赋值和基本数据类型

3403771864 / 597人阅读

  let和const

  let和const两者并不存在变量提升

  这里要说明的是变量一定要在声明后使用,否则报错。

  var a = [];
  for (var i = 0; i < 10; i++) {
  a[i] = function () {
  console.log(i);
  };
  }
  a[6](); // 10

  变量i是var声明的,我们要知道这里在全局范围内都有效。我们要知道在每一次循环中,新的i值都会覆盖旧值,这样就可以在最后输出的是最后一轮的i的值。

  var a = [];
  for (let i = 0; i < 10; i++) {
  a[i] = function () {
  console.log(i);
  };
  }
  a[6](); // 6

  我们可以看到在上面代码中,变量i是let声明的,要知道这个只有当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。

  暂时性死区(temporal dead zone,简称TDZ)

  这里要说的是当在块级作用域内存在let或const命令,则变量会被绑定在这个区域内,不受外层作用域的变量影响。凡在声明之前使用了变量,则会报错。

  注意,如果使用了let或const,typeof 就不安全了

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

  不允许重复声明

  let a = 10;
  var a = 1; //Uncaught SyntaxError: Identifier 'a' has already been declared

  或

  let a = 10;
  let a = 1; //Uncaught SyntaxError: Identifier 'a' has already been declared

  块级作用域与函数声明

  并且ES6规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。

  const

  const只保证变量指向的地址不变,不保证该地址的数据不变。

  const foo = {};
  foo.prop = 123;
  console.log(foo.prop); // 123
  foo = {}; // TypeError: "foo" is read-only

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

  const foo = Object.freeze({});
  // 常规模式时,下面一行不起作用;
  // 严格模式时,该行会报错
  foo.prop = 123; // Can't add property prop, object is not extensible

  变量解构

  解构必须左右解构相同

  1.解构失败则是undefined,如有默认值则取默认值

  2.左右解构不同则抛error

  // 报错
  let [foo] = 1;
  let [foo] = false;
  let [foo] = NaN;
  let [foo] = undefined;
  let [foo] = null;
  let [foo] = {};

  我们看到上面是报错,因为等号右边的值,要么转为对象以后不具备Iterator接口(前五个表达式),要么本身就不具备Iterator接口(最后一个表达式)。

  这里要说明的是只有当某种数据结构具有Iterator接口,由此在采用数组形式的解构赋值。例如set数据类型和Generate函数

  默认值

  解构赋值允许默认值,在定义的时候直接赋值即可

  var [x=1]=[,3];
  console.log(x) // x = 1

  注意,ES6内部使用严格相等运算符(===),判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。

  对象的解构赋值

  对象的解构与数组有一个重要的不同:数组的元素是按序排列的,取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

  对象解构赋值的内部机制:先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

  var {foo,bar} = {foo:'aaa',bar:'bbb'}
  等价于
  var {foo:foo,bar:bar} = {foo:'aaa',bar:'bbb'}

  默认值生效的条件同样是,对象的属性值严格等于undefined。

  注意赋值时不能让大括号在行首

  var x;
  {x} = {x: 1}; // 会报错,因为JavaScript引擎会将{x}理解成一个代码块
  var x;
  ({x} = {x:1}); // 正确写法

  字符串的解构赋值

  字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

  数值和布尔值的解构赋值

  解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

  函数的解构赋值

  function move({x = 0, y = 0} = {}) {
  return [x, y];
  }
  move({x: 3, y: 8}); // [3, 8]
  move({x: 3}); // [3, 0]
  move({}); // [0, 0]
  move(); // [0, 0]
  注意对比与下面代码的区别
  function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
  }
  move({x: 3, y: 8}); // [3, 8]
  move({x: 3}); // [3, undefined]
  move({}); // [undefined, undefined]
  move(); // [0, 0]

  此处是给{x,y}这个对象设置了默认值,而不是给x,y分别设置了默认值

  解构赋值的7种常见用法

  1.变量交换

  [x, y] = [y, x];

  2.从函数返回多个值

  function example() {
  return [1, 2, 3];
  }
  var [a, b, c] = example();

  3.函数参数的定义

  function f([x, y, z]) { ... }
  f([1, 2, 3]);

  4.提取JSON数据

  var jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
  };
  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结构

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

  7.输入模块的指定方法

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

  String

  字符串编码{}

  es5中超过ffff值的Unicode字符只能用两个字节表示,但是es6增加了大括号方式

  es5:
  "\uD842\uDFB7"
  // "????"
  "\u20BB7"
  // " 7"
  es6:
  "\u{20BB7}"
  // "????"

  还可以在变量中拼接Unicode编码

  let hello = 123;
  hell\u{6F} // 123

  新增方法

  1.codePointAt 获取字符的码点,10进制

  codePointAt方法是测试一个字符由两个字节还是由四个字节组成的最简单方法。

  function is32Bit(c) {
  return c.codePointAt(0) > 0xFFFF;
  }
  is32Bit("????") // true
  is32Bit("a") // false

  2.String.fromCodePoint() 返回传入码点的对于字符

  3.字符串Iterator接口新增,可以用for of遍历字符串

  4..at()能返回给定位置的字符串,允许超过FFFF的字符被返回,es5中对应的是charAt

  5.includes() 判断字符串中是否包含传入的字符

  6.startsWith() 判断字符串的起点是否是传入的字符

  7.endsWith() 判断字符串的终点是否是传入的字符

  8.repeate() 重复某字符

  9.padStart() 补全开头

  10.padEnd() 补全结尾

  模板字符串

  嵌入变量${}

  空格、缩进、换行会在输出是保留,可以trim消除

  字符串模板嵌套

  Number

  八进制和二进制写法

  二进制 0b开头

  八进制 0o开头

  新增方法

  Number.isNaN

  Number.isFinite

  Number.isInteger

  在JavaScript内部,整数和浮点数是同样的储存方法,所以3和3.0被视为同一个值。

  Number.EPSILON 极小的误差常量

  JavaScript能够准确表示的整数范围在-253到253之间(不含两个端点),超过这个范围,无法精确表示这个值。

  Number.isSafeInteger() 安全整数范围

  新增函数

  trunc 化零为整

  sign 判断正负数

  cbrt 计算平方根

  clz32 返回一个32位二进制

  **指数运算

  本篇文章主要就是为大家讲述ES6变量赋值和基本数据类型,欢迎大家关注更多精彩内容。


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/128817.html

相关文章

  • 【Step-By-Step】高频面试题深入解析 / 周刊07

    摘要:复杂数据类型变量,赋值给之后,只读引用与关联,和中存储的是同一个对象的堆内存地址,当这个对象的值发生改变时,此时的值也会发生变化。 不积跬步无以至千里。 关于【Step-By-Step】 Step-By-Step (点击进入项目) 是我于 2019-05-20 开始的一个项目,每个工作日发布一道面试题。每个周末我会仔细阅读大家的答案,整理最一份较优答案出来,因本人水平有限,有误的地方...

    superw 评论0 收藏0
  • 前端

    摘要:原理判断左边的左操作数的对象的原型链上是否有右边这个构造函数的属性。每个对象都有属性,但只有函数对象才有属性在默认情况下,所有的原型对象都会自动获得一个构造函数属性,这个属性是一个指针指向属性所在的函数原型对象是构造函数的一个实例。 JS JavaScript深入浅出 链接描述 数据类型 JS变量按照存储方式区分为值类型和引用类型,并描述其特点?js值类型和引用类型的区别 值类型...

    WilsonLiu95 评论0 收藏0
  • 闲话JavaScript数据类型

    摘要:支持的类型的内置数据类型罗列如下自定义自定义这三种类型的赋值是同类似的。这根不同,这因为是没有包装类新增的基本类型,只支持函数式赋值,不支持字面量和函数构造。 JavaScript支持的类型 JS的内置数据类型罗列如下: undefined null bool number string function object Function Date ...

    jerryloveemily 评论0 收藏0
  • javascript --- 数据类型

    摘要:其他字符可以是字母下划线美元符号或数字。在使用声明变量,但没有对其初始化时,这个变量的值就是。从逻辑上思考,他们的值,一个是,一个报错他们的类型,却都是。这时,可以采用变量的类型进行比较。类型有两个值字面量和。 javascript 数据类型 javascript由于nodejs的出现将触角延伸至各个开发领域, 也由于 ES6等后续版本的推出对程序员越来越友好, 收到程序员的强烈推崇,...

    darcrand 评论0 收藏0

发表评论

0条评论

3403771864

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<