写点什么

读深入 ES6 记 [四]

用户头像
Daniel
关注
发布于: 2021 年 06 月 11 日
读深入ES6记[四]

第七章:箭头函数


1.箭头符号,悠久的历史


以下写法是不是灰常眼熟啊,但你了解为啥要这样写吗?


这是为了兼容不支持 JS 的浏览器(现在应该跟恐龙一样绝迹了吧!)


不支持 JS 的浏览器:解析为两个不支持的标签<script></script>和一段 HTML 注释支持 JS 的浏览器:识别出 JS 代码,<!--// -->被解析为单行注释的开始


<script language="javascript">  <!--    console.log('Hello Daniel');  // --></script>
复制代码


2.节省


懒人必备良品:

可省去 function 关键字单语句可省去 return 关键字和大括号 {}单参数可省去小括号 ()


最省情况代码示例:


[1, 2, 3].filter(num => num > 1);
复制代码


非单参数代码示例:


[1, 2, 3].filter((num, idx) => idx > 1);
复制代码


非单语句代码示例:


[1, 2, 3].filter(num => { console.log(num); return num > 1; });
复制代码


3.注意事项


如果想简单返回对象,这个时候就不能偷懒,至少得加个小括号,不然会被解析为块代码。看下代码示例,第一和第二句都被当作块代码:


var result = [1, 2, 3].map(num => {}); // 这样相当于空代码,返回值为undefinedvar result = [1, 2, 3].map(num => {key: num}); // 这样的返回值同上var result = [1, 2, 3].map(num => ({key: num})); // 必须加个小括号
复制代码


4.与 function 关键字声明的函数的区别


  1. 没有自己的 this 值。this 值继承自外围作用域

  2. 没有 arguments 对象。这不是坏消息,因为我们有不定参数和默认值法宝


5.理解 this


提到this,你确定你对它真的了解吗?反正我刚好可以趁这个机会更加深入地了解它一番(这篇文章值得一看)。


this都是在函数内才能用到,我们来列举下常见的几种场景:


  • 场景一:调用对象的方法


var deep_thought = {  the_answer: 42,  ask_question: function () {    return this.the_answer;  }};
var the_meaning = deep_thought.ask_question();
复制代码


当 deep_thought.ask_question()执行时,Javascript 为函数建立执行上下文(execution context),将 this 设为函数所属的对象引用(即 deep_thought)


  • 场景二:构造函数


function BigComputer(answer) {  this.the_answer = answer;  this.ask_question = function () {    return this.the_answer;  }}
var deep_thought = new BigComputer(42);var the_meaning = deep_thought.ask_question();
复制代码


当用new关键字来创建构造函数的实例对象时,过程是这样的:先创建一个要返回的对象,然后将this指向它的引用,执行完函数代码后返回该对象。当执行 deep_thought.ask_question(),函数里的 this 指向的是构造函数的实例对象


  • 场景三:普通函数


function test_this() {  return this;}var i_wonder_what_this_is = test_this(); 
复制代码


因为我们没明确指定函数调用的上下文,所以默认是全局对象,在浏览器端为 window 对象,在 NodeJS 为 global 对象


  • 场景四:事件处理


这个还要看具体的写法:


写法一:this指向全局对象,这里即 window 对象


<script type="text/javascript">  function click_handler() {    alert(this); // alerts the window object   }</script>...<button id='thebutton' onclick='click_handler()'>Click me!</button>
复制代码


写法二:this指向 DOM 对象,因为触发事件的时候其实是DOM.onclick()


<script type="text/javascript">  function click_handler() {    alert(this); // alerts the button DOM node   }
function addhandler() { document.getElementById('thebutton').onclick = click_handler; }
window.onload = addhandler;</script>...<button id='thebutton'>Click me!</button>
复制代码


简单总结一下:函数内的this指向的是函数的执行者([执行者].fnName()),如果没指定执行者,则为全局对象


来个题目考考你呗,以下代码点击按钮会显示什么信息呢?


<script type="text/javascript">  function BigComputer(answer) {    this.the_answer = answer;    this.ask_question = function () {      alert(this.the_answer);    }  }
function addhandler() { var deep_thought = new BigComputer(42); var the_button = document.getElementById('thebutton');
the_button.onclick = deep_thought.ask_question; }
window.onload = addhandler;</script>
复制代码


答案是:alert 的内容是 undefined,因为 button DOM 是没有the_answer这个属性滴。这是为什么呢?大声念一遍上边的总结


this除了以上的默认规则外,你也可以手动指定this指向的值,applycall以及漂亮的bind就是用来干这事


上面的例子要 alert 出正确的值,改用bind手动指定this的值即可


function addhandler() {  var deep_thought = new BigComputer(42);  var the_button = document.getElementById('thebutton');
the_button.onclick = deep_thought.ask_question.bind(deep_thought);}
复制代码


好吧,没想到this讲了这么长的篇幅,我们马上进入第八篇吧。



第八章:Symbols


1.我是原始类型


Symbol 为 Javascript 的第 7 种原始类型。


Hi,大家,我是老七,我的大哥们分别是 Object,Boolean,String,Number,Null,Undefined


2.设计初衷


Symbol 的设计初衷就是避免冲突,一般应用于属性键的命名上。


有没一头雾水,那例子伺候吧。以下假设第三方库对象 libA 和 libB 都想对传入的对象进行属性值的修改,而属性的名称刚好相同,那么冲突就发生了


var libA = {  symbolIsShowKey: Symbol('isShow'),  stringIsShowKey: 'isShow',  fn: function (data) {    data[this.symbolIsShowKey] = true;    data[this.stringIsShowKey] = true;  }};
var libB = { symbolIsShowKey: Symbol('isShow'), stringIsShowKey: 'isShow', fn: function (data) { if (data[this.symbolIsShowKey]) { // 没被其它库干扰掉 console.log('Symbol.isShow is true: do something'); } if (data[this.stringIsShowKey]) { // 被其它库干扰到 console.log('String.isShow is true: do something'); } }};
var dataObj = {};libA.fn(dataObj);libB.fn(dataObj);
复制代码


3.注意事项


symbol 不能被自动转换成字符串,所以尝试将它与字符串拼接将报错,比如:


Symbol('daniel') +' some string' // 报错Symbol('daniel').toString() + ' some string' // 显式转换则OK
复制代码


4. 获取 symbol 的方式


  1. Symbol() 每次都返回新的唯一的 symbol,无论描述是否一样


console.log(Symbol('daniel') == Symbol('daniel'));
复制代码


  1. Symbol.for() 用于共享 symbol,描述作为 symbol 注册表中的键,描述相同,则每次取出的 symbol 值是相同的


console.log(Symbol.for('daniel') === Symbol.for('daniel'));
复制代码


  1. 使用标准定义的 symbol。如Symbol.matchSymbol.iterator等(还记得《读深入ES6记[一]》中我们如何让普通对象拥有for-of来遍历数据的特性吗)




这就是第七,八章的学习情况,接下来小期待下《读深入 ES6 记[五]》呗。


前面章节的学习情况请看:《读深入ES6记[一]》《读深入ES6记[二]》《读深入ES6记[三]》


--EOF--

发布于: 2021 年 06 月 11 日阅读数: 9
用户头像

Daniel

关注

一源一世界 2019.03.03 加入

ncform / ncgen / nice-hooks 开源项目作者

评论

发布
暂无评论
读深入ES6记[四]