Javascript 进阶 9-2 与传统函式不同之处

这篇文章要来介绍箭头函式跟传统函式的差别~

1. 箭头函式没有 arguments 参数

之前在传统函式有介绍到,参数的传入有一个 arguments 参数会来承接所有船入的参数,并且使用**类阵列(Array-liked)**的方式记录起来。

const nums = function () {    console.log(arguments);}nums(1,2,3,4,6,7,8,500,10);

http://img2.58codes.com/2024/20121770Lz0A7dz7Sg.png

但箭头函式则没有这个参数,那么当如果我们需要记录传进来的参数的时候,该怎么办呢?

const nums = () => {    console.log(arguments);}nums(1,2,3,4,6,7,8,500,10);

http://img2.58codes.com/2024/20121770hnX57aIxZQ.png

这个时候就可以使用其余参数运算子来解决这个问题,利用三个点+自定义变数名称,就可以将参数的内容以阵列的方式记录在变数上噜!

const nums = (...arg) => {    console.log(arg);}nums(1,2,3,4,6,7,8,500,10);

http://img2.58codes.com/2024/20121770iNz9UaxkjO.png

2. This 绑定的差异

箭头函式没有自己的 This,怎么说呢?

我们先来看看範例~

var myName = '全域';var person = {    myName: '小明',    callName: function () {        console.log('1', this.myName);        setTimeout(function () {            console.log('2', this.myName);            console.log('3', this);        }, 10);    }}person.callName();

看完这样的程式码,我们可以知道 callName 这个函式中,this的指向会是 person 这个物件。
另外,setTimeout 因为传入的是 callback function ,所以这里面的作用域的 this 指向是全域的物件 window。

结果很明显会是:

http://img2.58codes.com/2024/20121770K3rK7GohhE.png

那么我们稍微改动一下程式码,把 callback function 改成箭头函式的写法,看看 this 会怎么指向~

var myName = '全域';var person = {    myName: '小明',    callName: function () {        console.log('1', this.myName);        setTimeout(() => {            console.log('2', this.myName);            console.log('3', this);        }, 10);    }}person.callName();

http://img2.58codes.com/2024/20121770cBUtbQ7hJw.png

可以看到,this 的指向变成了外层作用域的 person。

那么这个时候,再把 callName 的传统函式也改成箭头函式的写法的话呢?

var myName = '全域';var person = {    myName: '小明',    callName: () => {        console.log('1', this.myName);        setTimeout(() => {            console.log('2', this.myName);            console.log('3', this);        }, 10);    }}person.callName();

http://img2.58codes.com/2024/20121770jSzsaiVvt6.png

很明显,改成箭头函式以后,this的指向就跑到全域的物件 window 身上。

而且不管埋几层都一样~

var odin = '1';var obj = {    odin: '2',    arrfn: () => {        console.log('2',this, this.odin)        setTimeout(() => {            console.log('2-setTimeout',this, this.odin)        }, 10);    },    obj: {        odin: '3',        arrfn: () => console.log('3',this, this.odin),        obj: {            odin: '4',            arrfn: function () { console.log('4',this, this.odin)},            obj: {                odin: '5',                arrfn: function () {                    console.log('5',this, this.odin)                    setTimeout(() => {                        console.log('5-setTimeout',this, this.odin)                    }, 10);                },            }        }    }};obj.arrfn();obj.obj.arrfn();obj.obj.obj.arrfn();obj.obj.obj.obj.arrfn();

只是如果改成传统函式的话,规则又会跟之前的一样,在被呼叫的时候,前一个的物件为 this 的指向。

http://img2.58codes.com/2024/20121770xTNeXHhNFW.png

3. This 不同,导致 DOM 的 This 指向也不同

const ele = document.querySelector('p');ele.addEventListener('click', function () {    console.log(this);});

一般来说,这样撰写以后,点击画面上的 p 元素,this 会指向该 p 元素的 DOM。

http://img2.58codes.com/2024/20121770burVdgAn7p.png

但如果用箭头函式撰写的话~

const ele = document.querySelector('p');ele.addEventListener('click', () => {    console.log(this);});

http://img2.58codes.com/2024/20121770BMbtT1VcOY.png

就会指向全域的物件 window 身上。

4. 也无法透过 call, apply, bind 重新给予 this 的指向

因为箭头函式没有自己的 this,所以就算使用 call, apply, bind 重新给予 this 的指向,也无法改变。

const family = {    myName: '小明家'};const fn = (para1, para2) => {    console.log(this, para1, para2);};fn.call(family, '小明', '杰伦');

http://img2.58codes.com/2024/20121770z8PIruj3aM.png

5. 不具有 prototype,故无法作为建构函式使用

const Fn = function (a) {    this.a = a;}const ArrowFn = (a) => {    this.a = a;}console.log('Fn', Fn.prototype);console.log('ArrowFn', ArrowFn.prototype);const instanceFn = new Fn('a');const instanceArrowFn = new ArrowFn('a');

http://img2.58codes.com/2024/20121770Bu588LzClA.png

以上就是五个传统函式与箭头函式不同的地方,其中第二点最容易搞混,要搞清楚再往下走会比较好喔!

没问题的话就继续吧!汪汪~


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章