雨碎江南

雨碎江南 查看完整档案

深圳编辑  |  填写毕业院校  |  填写所在公司/组织 consoles.github.io 编辑
编辑

风风雨雨寒寒暖暖处处寻寻觅觅,
莺莺燕燕花花叶叶卿卿暮暮朝朝。

个人动态

雨碎江南 回答了问题 · 2019-10-12

解决哈希表hash算法的冲突问题

大佬的回答然我茅塞顿开,根据您的提示写了下:

function hashCode(str) {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = hash * 31 + str.charCodeAt(i);
  }
  return hash;
}

// 寻找hash冲突

const hash1 = hashCode('Aa'); // 65 * 31 + 97
const hash2 = hashCode('BB'); // 66 * 31 + 66

// 某一位上的code-1,后一位的code+31,其他位置不变

// 可以推测出
// CC = Bb
// BBBB = BBAa

console.log(hash1, hash2);

function isAscii(charCode) {
  return charCode >= 65 && charCode <= 90 || charCode >= 97 && charCode <= 122;
}

function* buildStr(len) {

  const list = [];
  for (let i = 65; i <= 90; i++) {
    list.push(String.fromCharCode(i));
  }
  for (let i = 97; i <= 122; i++) {
    list.push(String.fromCodePoint(i));
  }

  const chars = new Array(len);

  function* _buildStr(chars, pos) {
    if (pos >= len) {
      return yield chars.join('');
    }
    for (let i = 0; i < list.length; i++) {
      chars[pos] = list[i];
      yield* _buildStr(chars, pos + 1);
    }
  }

  return yield* _buildStr(chars, 0);
}

function buildHashCode(n) {

  const len = 2 ** n;

  let results = [];

  const map = {};

  let maxHash = 0;

  for (const str of buildStr(len)) {
    const hash = hashCode(str);
    map[hash] = map[hash] || new Set();
    const charList = str.split('');
    const ret = [];
    _buildHashCode(charList, 0, ret);
    for (const item of ret) {
      map[hash].add(item);
    }
    if (map[hash].size >= len) {
      maxHash = hash;
      break;
    }
  }

  // 没有找到指定长度的,返回所有字符串中hash冲突最多的那些字符串
  if (maxHash === 0) {
    for (const hash of Object.keys(map)) {
      maxHash = Math.max(maxHash,map[hash].length);
    }
  }

  return [...map[maxHash]];

  function _buildHashCode(charList, pos, ret) {
    if (pos + 1 >= charList.length) {
      return;
    }
    let cur = charList[pos];
    let next = charList[pos + 1];

    let charCodeCur = cur.charCodeAt(0) - 1;
    let charCodeNext = next.charCodeAt(0) + 31;

    if (isAscii(charCodeCur) && isAscii(charCodeNext)) {
      charList[pos] = String.fromCodePoint(charCodeCur);
      charList[pos + 1] = String.fromCodePoint(charCodeNext);
      ret.push(charList.join(''));
    }
    _buildHashCode(charList, pos + 1, ret);
    charList[pos] = cur;
    charList[pos + 1] = next;
  }
}

const ret = buildHashCode(2);
for (const str of ret) {
  console.log(str, hashCode(str));
}

输出结果:

2112 2112
Aaaa 2032736
AabB 2032736
AbBa 2032736
AbCB 2032736

对于种子字符串的生成,我目前采用的是生成字符串的全排列,然后从中选取,不知道你还有别的建议不?

关注 4 回答 3

雨碎江南 赞了回答 · 2019-10-12

解决哈希表hash算法的冲突问题

放在主回答里哈。。。

给个思路哈,我们可以认为最终的hash是31进制数,那么我们可以通过以下步骤来从一个字符串构造另一个hashCode相同的字符串:
1.某个位置上的code-31
2.它的前一个位置上的code+1

为了得到合法的字符串,我们要保证code-31和code+1得到某个字母的编码。例如:'y'的编码值为121,121-31=90刚好为'Z'的编码值。

接下来来构造吧,首先有一个字符串xxxxxxxxyy(这里x代表任意字母)我们把最后一个y-31,得到'Z',倒数第二个y+1,得到'z',所以hashCode("xxxxxxxxyy")==hashCode("xxxxxxxxzZ")。前面n-2个x可以随机有52^(n-2)个。为什么是52,26个大写字母,26个小写字母。
然后最后两个yy改成xx继续上面的过程。
这样的字符串你可以得到非常多个。

================ 以下是原回答 ===================
题目感觉有点矛盾,如果按照hashCode算法的实现,hashCode('Aa')肯定不等于hashCode('BB')

下面几组也不可能相等。

关注 4 回答 3

雨碎江南 提出了问题 · 2019-10-11

解决哈希表hash算法的冲突问题

已知字符串的hash算法如下:

function hashCode(str) {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = hash * 31 + str.charCodeAt(i);
  }
  return hash;
}

找出2^n个hashCode方法返回值相同,且长度为2^n的字符串,提示:hashCode('Aa') == hashCode('BB')。如下图所示:

image.png

根据例子可以推论如下:

CC == Bb
DD == Cc
BBBB == BBAa

但是如何找出全部的2^n个字符串还是一点思路都没有

关注 4 回答 3

雨碎江南 提出了问题 · 2019-09-26

关于TCP四次挥手的疑问

本机ip:192.168.1.77

客户端和服务器在一台机器上抓包如下:

clipboard.png

可以看出是4次挥手。但是在192.168.3.104主机上开启服务器,在客户端抓包就是如下结果:

clipboard.png

为什么抓包的结果变成了3次挥手?

关注 2 回答 1

雨碎江南 提出了问题 · 2019-08-29

解决nodejs事件循环的疑问

代码如下所示,第一层的输出顺序1 7 6 8没有疑问,主要是两个setTimeout内部的执行顺序:

console.log('1');

setTimeout(function() {
  console.log('2');
  process.nextTick(function() {
    console.log('3');
  })
  new Promise(function(resolve) {
    console.log('4');
    resolve();
  }).then(function() {
    console.log('5')
  })
})
process.nextTick(function() {
  console.log('6');
})
new Promise(function(resolve) {
  console.log('7');
  resolve();
}).then(function() {
  console.log('8')
})

setTimeout(function() {
  console.log('9');
  process.nextTick(function() {
    console.log('10');
  })
  new Promise(function(resolve) {
    console.log('11');
    resolve();
  }).then(function() {
    console.log('12')
  })
})

现在的输出顺序有2种:

clipboard.png

但是node.js v12.7.0中测试很多次貌似只有一种输出顺序

1
7
6
8
2
4
3
5
9
11
10
12

有没有大佬能解释下啊,网上的各种讲事件循环的都是看得云里雾里。

关注 2 回答 1

雨碎江南 评论了文章 · 2019-01-02

2018年,一个无名小子的复盘清单!

2017年一样,2018年也给自己定下了一个任务,就是在得到《每天听本书》听 300 本以上,至少订阅一个以上的大小专栏并完成学习!

图片描述

如图,这个小任务,今年算是完成了。

工作上

2017年 11月离开工作快 2 年的的初始公司(就是 16 年毕业实习及转正的公司),感谢这家公司给了自己机会,让我有所成长,也结识了几位好朋友,快三年了,这几个朋友直到到现在算是最好的朋友了。

离开这家公司到了一家上市公司,第一次进入是 UI 部门,主要是做静态页面,那时自己的内心想法是:这个对自己完全没有挑战,每次都在想是不是自己太冲动了,为什么没有考虑清楚自己想要的是什么在去跳槽,这个也渐渐让自己对这方面选择有了些经验。

工作了2个月,能力算还行,就被派出去出差了一次,这一次算是第二次到北方,也是第一次见到真正的雪,出差的最后一天,去了零下的30多度的《冰雪大世界》,真正切身感受了雪与冰结合的魅力,以下附上几张图片:

那里可能也只有我穿板鞋了

图片描述

1801月就被调到了研发部门,到了研发部门,我第一次使用 vue 来开发,因为第一家公司受限了内网,像需要外网的环境语言,只是平时底下练习了解而已,并没有真正实战经验(这个也是自己离开第一家公司的主要原因)1月到7月这半年期间就开始疯狂开始学习 vue,看各种跟 vue 有关的书及视频,在这半年锻炼里,最后算是可以使用 vue 独立开发了!

当然期间有苦有乐,苦的是2017年底开始的作息时间就调整为凌晨的 01:30 ~ 02:00 入睡觉 ,早上 7:00 起床 (礼拜例外),前面一开始是非常不适应,早上容易犯困,但随着一个月两个月三个月的适应,到现在渐渐的习惯了。来这家公司又调整了一些,就是礼拜如果没有什么事情基本都会来公司自己学习。这种调整,让自己学会了如何与孤独相处,当你能与孤独相处,有时就能开启心流模式:专注眼前,不会受到外界影响也不会使自己内心欲动,如,节假日别人都在约会看电影,今天抖音上又有什么好玩的等等。

算了一笔账,这样的作息习惯能让我比大部分人每天多出 3 ~ 4 个小时,一年下来就是 1000 多个小时,这也作为一个不是很聪明的人来说,最后想成长成为自己想要的样子,算是一个最好选择吧。

这里可能有人会说,你这样的生活也太无趣,其实这年我收到可能最多的一个疑问就是:你要有自己的生活,我每次听到这个问题,要么就是懒得回,要么就是应付一声“哦”,每个都有自己生活的方式,有人选择看剧,刷抖音、头条,有人选择旅游,爬山等等!而以上的作息就是我生活的一部分,所以有些说要有自己的生活,我就很纳闷了,我现在不就是在自己生活里么!

你的问题可能就是别人解决方案,如:你用吸烟有害健康的角度,来劝说别人不要吸烟!其实这个道理谁不知道呢!吸烟在你这里是一个问题,在那吸烟者的角度,有可能是他为了缓解生活上的压力、情绪、孤独的一种解决方案。所以如果你没有一个能让他彻底改变的方案,最好不要轻意去建议别人怎么做!因为,有时,你的建议或者劝说根本不会改变他什么,甚至会让他觉得很可笑!

图片描述

在这家上市公司工作9个月后,期间渐渐发现团队的氛围可能与自己的定位不太一样,不太适合自己的成长,所以工作9个月,为了做更有挑战的事及能快速提升自己的能力环境,自己就去了一家刚创业的公司。

当然不是说我与同事关系不好,实际我跟同事的关系都挺好的,大家也比较喜欢我(哈哈,自恋一下),有图为证(只有这张图,平时很少拍照):

红色那个毛衣就是我

201810 月来到一创业公司,因为是创业公司,最后因为资金的问题,所以工作三个月后就关闭了,这三个月的时间也学到了很多,比如使用 vue 开发后台管理,这个折磨了我快一个月,最后算是搞清楚(这个也是为我现在待的这个公司打下基础,能快速熟悉环境,能独立的开发)。

在创业公司,也真正体会到创业的公司的艰难,想跟人合作,别人嫌弃你公司太小,利润不够诱惑,如果没有特别关系或者特别好的项目,懒都懒得理你,这三个月的时间里,自己的心智模式也得到很大的提升,很少在像之前那样遇到不会的,脾气就会变得暴躁,而是能静下心来去查找资料(因为想问别人没有人,只有一个前端)最后把问题解决。

2018年10月中旬,来到一个还算不错公司,做教育相关的,因为目前只来了 2 个多月,这里就不展开说了,19 年的总结在细说!

生活上

图片描述

18年03月06日,凌晨 01:41segmentfault 开启第一个专栏 《终身学习者》,这也是自己今年比较有大的变化,一开始只是分享自己项目遇到的一些问题,方便以后在遇到些类问题,能快速的解决。

在第5天后,分享 5 篇,收到了第一赞,把我兴奋的要死:

图片描述

接着一直到 10月5日,这快7个月时间,自己的声望才在达到 1000:

图片描述

这期间也认识到了一个名为 浪里行舟, 同样在 segmentfault 写文章的, 他一开始私信我说:

clipboard.png

其实从对话中就可以看出,我一看就没太在意他,以为只是请教一些问题而已,看他写的文章点赞,关注人数都不是很多,就没太多的关注。直到1个月过后,我看下了一上 SF 的每周分数排行版,waht? 这个不是我之前认识的 浪里行舟 吗,就一个月多月声望就超过我写半年的才获取得到的,接着,再过去了一个月了,在去看了一上,这增长速度有点恐怖,于是我就去请教了他,他告诉了我一些技巧,然后我在对比我跟他写的文章,总结以下几点:

  1. 他的文章结构清晰,篇幅完整,而我的只是讲诉一些内容,讲到哪里算到哪里。
  2. 推荐参考并不是很多,对别人有用的干货少之又少。

接着我试着用他的方式,整理了一些文章,效果是出奇的好:

clipboard.png

从前面少之又少的点赞到后台每篇至少有20个赞以上,收货挺多的。

分享最大的受益者可能就是分享者

分享是一个相互学习的过程,分享者会不断收到反馈,哪些不好点的,哪些需要我们改进的,当然更重要的是心态,分享过程也是一个容易被喷的过程,要处理,忍受,看待这些,需要时间的沉淀,这也是磨练自己心态一种好的方式。

其实这期间也收到一些人的投诉,说是抄袭,还有文章没营养等! 就这些事情,我对待抄袭态度是抄没抄袭对比一下就清楚了。对于文章有没有营养,这点是我比较在意的,确实现在如果文章点赞少于 10 个,我都会删除在重新整理,如果是涉及专业程度上,这个我也在不断加强中,需要一个过程。

对于那些喷嘴,我的感受的是:当自身没有做好的时候,就该去反思自己哪里做的不好,多跟别人学学,而不是一味抱怨自己,怪别人!学不会这个,那你永远都在抱怨别人的道路上,一条路到摸到黑!

在这里特别感谢 浪里行舟 这位朋友,你的建议让我在整理或者写文章上有了进一步的认识!

也用罗胖的话来提醒一下自己:

千万不要把自己当主流,你要对自己的趣味保持一种警醒和谦卑。千万不要动不动就以己度人 ---- 罗振宇

当然生活上不止只是写文章,看书也是我生活中的一种方式,以下是我看书的类别:

图片描述

英语小说 ---- 为了加强自己的英文,意外的发现一种好的学习方式,就是看英语小说,结合里面的故事情节更容易让人记住。

专业书 ---- 专业书也是提高自己专业能力一种好的学习方式,毕竟我们得靠自己的专业能力吃饭。

课外书 ---- 课外书也是提高自己认知的的一种好的学习方式,推荐古典老师的几本书《拆掉思维里的墙》,《跃迁》,《你的生命有什么可能》还有吴军全套及王小波等!

我比较喜欢纸质书,可能纸质的比较有实体感。阅读是提高自己表达能力,认知必备的一项技能,那些高手们,每年的阅读量都是很惊人的,所以接下,阅读也是自己长期坚持做的一件事!

图片描述

18年11月30日,给自己报了吉他培训班,记得高中那会,特羡慕那些抱着吉他自弹自唱的人儿,那时家里没钱,没法报班培训,结果学了学费比较便宜的街舞,大学参加表演活动那会,再次在舞台上看到那些自弹自唱人儿,心里想,自己以后老了肯定会抱着吉他在街上或者公园自弹自唱里的一个老头!

每天在思考提醒自己,自己卖命的打拼着是为了啥,除了让自己爱的人幸福,更多的就是让自己成为自己想成为的,对,那就去做吧,何必非得等到老了以后呢?

2019年目标(方向)?

我在前面已经没有说什么18年的目标,当然19年我也不会给自己定个目标,相反的我会说给自己一个方向或者任务,现在世界变化很快很快,快到我们时常都跟不上,如:18年我不知道我自己会翻译整理文章,更不会想到我会学吉他,阅读倒是有,但读哪些类型我是不清楚的,所以你让我说,19年我要读20本书,这种量化的目标我在17年也做过,效果不是很好,很可能到最后只了为了完成而完成而已,虽然是把20本书读完,在这过程你可能没有比细读几本的来的收获更大,所以对我自己来说,我只说19年我的方向(任务)有一个是多读一些课外书。

列出19年自己想要做的方向:

  1. 继续整理更多有干货的文章,然后尽量有自己的好的原创文章。
  2. 把吉他练好,让自弹自唱成为自己生活的一部分。
  3. 专业上继续深入
  4. 多读一些课外书

2018下半年,整片都是在叫经济不好,很多公司裁员的裁员,减薪的减薪,19年要怎么办呢?昨晚看到了老罗的跨年演讲,最后一段,老罗引用一句话:

中国是什么?它是好多好多全世界最勤奋、最想通过努力改变命运的一群人组成的。

对于19年,最聪明的做法,就是做一个理性乐观派。只有这个选择既符合我们的理性,也符合我们的情感,还符合我们的利益。靠着我们的勤奋做下去吧!

面对社会趋势的巨大不确定性,最佳的策略就是保持自己的确定性,那些能够坚持自己的看法,不轻易随波逐流、看起来很“”的人,将更容易脱颖而出。

最后,哈哈

元旦回去了一天,每次回家,家人都在说对象呢?有时实在很烦,我天天在 new 对象,已经看烦了,不太想找,哈哈(悲哀的人给自己打气的方式)!附上自己最近的一张照片,希望能更快遇到合适的人吧!

图片描述

还没完呢

最后,用我最喜欢的一段话来结束 18 年的总结:

真实世界总是不尽人意,永远都有各种无奈,永远都是矛盾,这意味着人生并没有先天设定的意义。活在当下还是着眼未来,献身工作还是回归家庭,眼前的苟且还是诗和远方,这些问题没有简单的答案。但是有一点,真实世界比任何故事都好:它充满惊奇的刺激。因为这一点,也许你可以把“体验真实世界”当成人生的意义。


你的点赞是我持续分享好东西的动力,欢迎点赞!

一个笨笨的码农,我的世界只能终身学习!

查看原文

雨碎江南 回答了问题 · 2018-12-24

解决node.js中await会造成内存泄漏?

补充2个图,导出堆快照后使用阿里云的nodejs性能平台分析如下:

clipboard.png
clipboard.png

回答中又说尾递归的,有说promise没有销毁的,但是为啥我同样是递归的写成这样就不会有内存泄漏:

async function start() {
    await sleep(3);
    await doTask();
    start(); // 不await了,直接递归
}

关注 8 回答 7

雨碎江南 提出了问题 · 2018-12-24

解决node.js中await会造成内存泄漏?

最小复现代码:

test.js

function sleep(delay) {
    return new Promise(resolve => setTimeout(resolve, delay));
}

const _ = require('lodash');

async function doTask() {
    // console.log('start');
    await sleep(_.random(10, 30));
    // console.log('done');
}

async function start() {
    await sleep(3);
    await doTask();
    await start(); // 去掉前面的await就好了
}

start();

setInterval(() => {
    console.log(process.memoryUsage());
},10e3);

进程启动的时候rss是22M,运行了1个多小时后内存占用达到了380M

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
30211 devel     20   0 1229m 381m  10m S  1.0  9.6   1:36.63 node test.js
# 在start函数的递归调用中取消await
21729 devel     20   0  867m  23m  10m S  1.0  0.6   1:22.73 node test.js
# 改成循环
14498 devel     20   0  867m  24m  10m S  1.0  0.6   1:11.04 node test.js

虽然确定是在递归调用的时候前面多加了个await,但是能解释下原因么,是我使用的姿势不对么

关注 8 回答 7

雨碎江南 评论了文章 · 2018-09-27

正则表达式的奇淫技巧

驼峰名转下划线:

'componentMapModelRegistry'.match(/^[a-z][a-z0-9]+|[A-Z][a-z0-9]*/g).join('_').toLowerCase(); // component_map_model_registry

获取URL参数

function wordCount(data) {
  var pattern = /[a-zA-Z0-9_\u0392-\u03c9]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af]+/g;
  var m = data.match(pattern);
  var count = 0;
  if( m === null ) return count;
  for (var i = 0; i < m.length; i++) {
    if (m[i].charCodeAt(0) >= 0x4E00) {
      count += m[i].length;
    } else {
      count += 1;
    }
  }
  return count;
}

var text = '贷款买房,也意味着你能给自己的资产加杠杆,能够撬动更多的钱,来孳生更多的财务性收入。';
wordCount(text); // 38

特殊字符转义

function htmlspecialchars (str) {
  var str = str.toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, '&quot;');
  return str;
}

htmlspecialchars('&jfkds<>'); // "&amp;jfkds&lt;&gt;"

格式化数量

// 方法一
function formatNum (num, n) {
  if (typeof num == "number") {
    num = String(num.toFixed(n || 0));
    var re = /(-?\d+)(\d{3})/;
    while (re.test(num)) num = num.replace(re, "$1,$2");
    return num;
  }
  return num;
}

formatNum(2313123, 3); // "2,313,123.000"

// 方法二
'2313123'.replace(/\B(?=(\d{3})+(?!\d))/g, ','); // "2,313,123"

// 方法三
function formatNum(str) {
  return str.split('').reverse().reduce((prev, next, index) => {
    return ((index % 3) ? next : (next + ',')) + prev
  });
}

测试质数

var arr = 'abcdaabc';

var info = arr
    .split('')
    .reduce((p, k) => (p[k]++ || (p[k] = 1), p), {});

console.log(info); //{ a: 3, b: 2, c: 2, d: 1 }

如何优雅的实现金钱格式化:1234567890 --> 1,234,567,890

var test1 = '1234567890'
var format = test1.replace(/\B(?=(\d{3})+(?!\d))/g, ',')

console.log(format) // 1,234,567,890

代码来自于收集,方便学习

查看原文

雨碎江南 评论了文章 · 2018-09-26

总结下var、let 和 const 的区别

前言

var 和 let 的区别是老生常谈,看到网上一些文章的总结,有的不太全面,甚至有的描述不太准确,在这里尽量全面的总结下这三者的区别。


let 是 ES6新增的变量类型,用来代替 var 的一些缺陷,跟 var 相比主要有以下区别:

1. let 使用块级作用域

在 ES6之前,ES5中js只有全局作用域和函数作用域,例如:

if(true) {
   var a = 'name'
}
console.log('a',a) // name

作用域是一个独立的地盘,让变量不外泄出去,但是上例中的变量就外泄了出去,所以此时 JS 没有块级作用域的概念。

var a = 1;
function fn() {
   var a = 2;
   console.log('fn',a);
}
console.log('global',a);
fn();

全局作用域就是最外层的作用域,如果我们写了很多行 JS 代码,变量定义都没有用函数包括,那么它们就全部都在全局作用域中。这样的坏处就是很容易冲突。
ES6中加入块级作用域之后:

if(true) {
   let a = 'name'
}
console.log('a',a) // Uncaught ReferenceError: a is not defined

块作用域内用 let 声明的变量,在块外是不可见的,如果引用的话就会报错。

2. let 约束了变量提升而不是没有变量提升

在 js 中变量和函数都会提升:

function fn() {
   console.log('a',a);
   var a = 1;  // undefind
}
fn()

a其实已经在调用前被声明了,只是没有被初始化。JavaScript会把作用域里的所有变量和函数提到函数的顶部声明,相当于:

function fn() {
   var a;
   console.log('a',a);
   a = 1;  // undefind
}
fn()

JavaScript会使用undefined缺省值创建变量a,事实上浏览器并没有把声明语句放到作用域的顶部,在编译阶段,控制流进入域,该域所有的变量和函数的声明先进入内存,文中代码的相对位置不会变动。

变量提升指的是变量声明的提升,不会提升变量的初始化和赋值。

并且函数的提升优先级大于变量的提升:

function fn() {
            console.log('a', a);
            var a = 1;
            function a () {
                console.log('I am a function');
            }
        }
        fn() // ƒ a () {console.log('I am a function');}

在上例中, let 声明的变量的作用域之外引用该变量会报错,但是否可理解为 let 没有变量提升?

let a = 'outside';
if(true) {
   console.log(a);//Uncaught ReferenceError: a is not defined
    let a = "inside";
}

报出错误 a 没有被定义,而不是引用了全局作用域里的 a,说明 let 声明的 a 也被提升了。

原因是 let 设计中的暂时性死区:
当前作用域顶部到该变量声明位置中间的部分,都是该let变量的死区,在死区中,禁止访问该变量。由此,我们给出结论,let声明的变量存在变量提升, 但是由于死区我们无法在声明前访问这个变量。

3. let 禁止重复声明变量

使用 var 可以重复声明变量,但是 let 不允许在同一块作用域内重复声明同一个变量:

function fn (){
   var a = 1;
   let a = 2;
   console.log(a); //SyntaxError
}

function fn (){
   let a = 1;
   let a = 2;
   console.log(a); //SyntaxError
}

function fn (a){
   let a = 2;
   console.log(a); //SyntaxError
}

上述代码会报语法错误;

4. let不会成为全局对象的属性

我们在全局范围内声明一个变量时,这个变量自动成为全局对象的属性(在浏览器和Node.js环境下,这个全局对象分别是windowglobal),但let是独立存在的变量,不会成为全局对象的属性:

var a = 1;
console.log(window.a); //1

let b = 2;
console.log(window.b); // undefined

5. const 声明的常量

以上 let 的规则同样适用于 const,但是跟 let 的区别是 const 声明的变量不能重新赋值,所以 const 声明的变量必须经过初始化

const a = 1;

a = 2; // // Uncaught TypeError: Assignment to constant variable
const b; // Uncaught SyntaxError: Missing initializer in const declaration

最后

以上大概是总结后的内容,看来,还是多用 let 、const 吧。

参考资料:http://es6.ruanyifeng.com/#do...
查看原文

认证与成就

  • 获得 82 次点赞
  • 获得 28 枚徽章 获得 2 枚金徽章, 获得 7 枚银徽章, 获得 19 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2015-07-13
个人主页被 1.1k 人浏览