今天来讲解 this
相关的陷阱题
myName = '全域';
var person = {
myName: 'weiwei',
getName: function(){
return this.myName;
}
}
var getName = person.getName;
console.log(getName());
此时的 this
会指向全域,
因为 getName()
这种呼叫方式为简易呼叫(Simple Call),
而此时的 this
只会跟呼叫方式有关,与定义过程无关
myName = '全域';
var obj = {
myName: 'weiwei',
fn: function(a, b, c){
return `${this.myName},${a},${b},${c}`;
}
}
var fnA = obj.fn;
var fnB = fnA.bind(null, 0);
console.log(fnB(1, 2));
此时会显示 全域,0,1,2
,因为在非严谨模式下,
bind
所代入的 this
值为 null
,则函式中的 this
会指向全域,
而函式中的参数虽然在定义 fnB
时,只有带入 0
,
但在 fnB(1, 2)
会将未取得值的参数依序代入值,
所以此时的 b
、 c
分别代入 1
、 2
的值,
如果我们要显示 null,0,1,2
的话,可以将程序码改成
myName = '全域';
var obj = {
myName: 'weiwei',
fn: function(a, b, c){
'use strict';
return `${this},${a},${b},${c}`;
}
}
var fnA = obj.fn;
var fnB = fnA.bind(null, 0);
console.log(fnB(1, 2));
此时只需将函式改为严谨模式,并且将函式中的 myName
去掉,
即可取得 null,0,1,2
这个值
var value = 'global';
var foo = {
value: 'local',
bar: function(){
return this.value;
}
}
// 直接执行
console.log(foo.bar());
// 赋值
console.log((foo.bar = foo.bar)());
// or
console.log((false || foo.bar)());
我们先看直接执行的部分,
在直接执行时,物件中 bar()
的 this
会指向前面的 foo
,
因此会回传 local
,
接着讲解後面两个部分,
这两个的概念基本上是一样的,
foo.bar = foo.bar
和 false || foo.bar
都是表达式,
因此都会回传值,而回传值都是 bar
函式本身
而它的执行方式就跟简易呼叫一样,因此此时 this
会指向全域,
所以会回传 global
var arr = [1, 2, 3].map(parseInt);
console.log(arr);
这题会回传 [1, NaN, NaN]
,
我们先看 map()
,map()
的 ()
内为 callback function,
而所代入的前两个参数分别为『阵列的值』、『值的索引位置』,
详细说明可到 MDN 文件 中观看,
接者我们看 parseInt()
,parseInt()
中能带入两个参数,分别为『待转成数字的字串』、『进位数字』,
详细说明可到 MDN 文件 中观看,
所以这题的 parseInt()
中,所接收到的参数的值是『阵列的值』以及『值的索引位置』,
看完以上说明,可以将这题写成以下型式
var arr = [1, 2, 3].map(function(item, i){
return parseInt(item, i)
});
console.log(arr);
而在 parseInt()
的 MDN 文件 中有写到,当第二个参数为 0 时的情况:
如果 radix 是 undefined 或 0(或留空)的话,JavaScript 会:
- 如果 string 由 "0x" 或 "0X" 开始,radix 会变成代表十六进位的 16,并解析字串的余数。
- 如果 string 由 0 开始,则 radix 会变成代表八进位的 8 或十进位的 10,但到底会变成 8 还是 10 则取决於各实做。ECMAScript 规定用代表十进位的 10,但也不是所有浏览器都支持。因此,使用 parseInt 时一定要指定 radix。
- 如果 string 由其他字串开始,radix 就会是十进位的 10。
如果第一个字串无法被解析为任何数字,parseInt 会回传 NaN。
这边直接针对呈现的结果来说明
parseInt(1, 0)
:因为第二个参数为 0,而以 MDN 文件说明来看,又因为第一个参数为 1,而非 0 或 0x 开头,因此会是十进位,所以回传 1
parseInt(2, 1)
:使用 1 来进位的数字根本不存在,因此回传 NaN
parseInt(3, 2)
:这是使用二进位,而在二进位中不会有 3 这个数,因此回传 NaN
以上就是今天的内容,终於完赛了,感谢观看!!
<<: Day15 - BST(Delete Case 1)
>>: Day 15 - Asynchronous 非同步进化顺序 - Callback 与 Promise
NAT 网路位址转换(英语:Network Address Translation,缩写:NAT)是...
在本地化 (localize) 文字讯息时,我们可能会遇到某些语言会有复数型态的状况 (最常见的就是...
寄送会员通知信 Laravel基於SwiftMailer函式库开发了一套邮件套件, 可以支援多种服务...
前几天我们已经将 AWS VPC 日志启用并将其资料转换让 BI 工具可以进行视觉化仪表板的建置,那...
让我一个字一个字解开你的心。 串流密码(stream cipher)跟区块密码(block ciph...