第七章:箭头函数
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 关键字声明的函数的区别
没有自己的 this 值。this 值继承自外围作用域
没有 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
指向的值,apply
和call
以及漂亮的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 的方式
Symbol() 每次都返回新的唯一的 symbol,无论描述是否一样
console.log(Symbol('daniel') == Symbol('daniel'));
复制代码
Symbol.for() 用于共享 symbol,描述作为 symbol 注册表中的键,描述相同,则每次取出的 symbol 值是相同的
console.log(Symbol.for('daniel') === Symbol.for('daniel'));
复制代码
使用标准定义的 symbol。如Symbol.match
,Symbol.iterator
等(还记得《读深入ES6记[一]》中我们如何让普通对象拥有for-of
来遍历数据的特性吗)
这就是第七,八章的学习情况,接下来小期待下《读深入 ES6 记[五]》呗。
前面章节的学习情况请看:《读深入ES6记[一]》《读深入ES6记[二]》《读深入ES6记[三]》
--EOF--
评论