读深入ES6记[四]

作者: 蛋先生DX | 来源:发表于2016-07-23 22:30 被阅读133次
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 => {}); // 这样相当于空代码,返回值为undefined
var 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--

相关文章

  • 读深入ES6记[四]

    第七章:箭头函数 1.箭头符号,悠久的历史 以下写法是不是灰常眼熟啊,但你了解为啥要这样写吗? 这是为了兼容不支持...

  • 读深入ES6记[三]

    第五章:不定参数和默认值 1.解决的问题 可用来代替arguments,解决它存在的可读性和参数索引的问题。用个栗...

  • 读深入ES6记[一]

    划重点了,有没像期末考时老师给题目范围的感觉,呵呵。 该笔记系列主要是在阅读深入ES6系列文章时,自己印象较为深刻...

  • 读深入ES6记[二]

    第三章:生成器(Generator) 1.解决的问题 当前可以总结出来的是 简化代码 和 解决回调地狱 ,举个栗子...

  • 读深入ES6记[五]

    第九章:使用Babel和Broccoli来编写ES6 1.流行的转译器 转译器,即源代码到源代码的编译器 非标准J...

  • 深入解析 ES6:Collections

    深入解析 ES6:Collections 原文链接:ES6 In Depth: Collections 前段时间,...

  • 读《深入理解ES6》

    第一章:块级作用域绑定 块级声明 1.var声明及变量提升机制:在函数作用域或者全局作用域中通过关键字var声明的...

  • ES6 数组新用法(二)

    《深入理解ES6》阅读随笔 find() find 方法接收一个函数作为参数,用于筛选寻找数组中满足条件的第一条记...

  • ES6——Reflect 与 Proxy

    ES6 之 Proxy 介绍深入实践 ES6 Proxy & Reflect 1.Proxy Proxy 可以对目...

  • 深入《学记》(四)

    大学之教也,时教必有正业,退息必有居学。不学操缦,不能安弦;不学博依,不能安诗;不学杂服,不能安礼。不兴其艺,不能...

网友评论

    本文标题:读深入ES6记[四]

    本文链接:https://www.haomeiwen.com/subject/osnijttx.html