侧边栏壁纸
博主头像
神奇的程序员

今天的努力只为未来

  • 累计撰写 167 篇文章
  • 累计创建 25 个标签
  • 累计收到 215 条评论

目 录CONTENT

文章目录

ECMAScript查漏补缺

神奇的程序员
2020-05-17 / 0 评论 / 1 点赞 / 381 阅读 / 2,003 字 正在检测是否收录...

前言

读《学习JavaScript数据结构与算法(第三版)》这本书时,发现书中讲到的一些知识点蛮有趣的,后续将持续分享这本书的观后感😊

接下来就跟大家分享下我在读这本书中ECMAScript章节中遇到的一些有趣的知识点,欢迎各位感兴趣的前端开发者阅读本文。

展开运算符

ES6中新增了展开运算符(...),在函数中使用展开运算符可以当作剩余参数使用。

例如,函数中有多个未知参数时,可以使用展开运算符来描述他们,下述代码在控制台打印了函数通过展开运算符传进来的未知参数,将已知参数和未知参数的长度做加法运算,将计算结果返回。

const argumentsTest = (x,y,...args)=>{
    console.log(args)
    return x + y + args.length;
}
  • 测试上述代码是否正确
console.log("展开运算符在函数中的使用",argumentsTest(12,15,"test",12,7,8));

arguments对象

arguments对象是所有非箭头函数中都可用的局部变量,arguments对象包含了传递给当前函数的每个参数,第一个参数在索引0处。

可以使用arguments对象,实现上述函数中使用展开运算符获取函数传进来的未知参数。

const argumentsJS = (x,y)=>{
    let a = Array.prototype.slice.call(arguments,2);
    return (x + y) * a.length;
}
console.log("展开运算符在函数中的使用(arguments)",argumentsJS(12,15,"test",12,7,8));

运行上述代码,我们后发现一个有意思的事情发生:

  • 箭头函数中不存在arguments对象,使用deno和浏览器控制台运行上述代码时,会报未定义的错。

  • 使用node执行上述代码,我们发现可以正常执行。

那么问题来了,箭头函数中不是没有arguments对象吗,为啥node执行他就能正常运行呢?

  • 为了找到答案,我们将函数中的arguments对象打印出来看看。
const argumentsJS = (x,y)=>{
    console.log(arguments);
    let a = Array.prototype.slice.call(arguments,2);
    return (x + y) * a.length;
}
console.log("展开运算符在函数中的使用(arguments)",argumentsJS(12,15,"test",12,7,8));
  • 执行后,我们发现使用node执行时arguments使用的是window对象中的arguments,上述疑问也就得到了答案。

构造函数内部方法的合理声明

在构造函数内部声明方法有两种方式:

  • 直接在函数内部声明
  • 将要声明的方法挂载到原型

函数内部直接声明

我们可以在函数内部直接声明一个变量,接收一个函数,代码如下:

const testFun = function (name,title) {
    this.name = name;
    this.title = title;
    this.printResult = function () {
        console.log(this.title+" " +this.name);
    }
}
  • 测试上述代码是否正常运行
const book = new testFun();
book.name = "aa";
book.title = "标题";
book.printResult();

挂载至原型

我们可以将要声明的方法,挂载至构造函数的原型上,代码如下:

const testFun = function (name,title) {
    this.name = name;
    this.title = title;
}
testFun.prototype.printResult = function () {
    console.log(this.title+" " +this.name);
}
  • 测试上述代码是否正常运行
const book = new testFun();
book.name = "aa";
book.title = "标题";
book.printResult();

最佳方案

我们发现上面两种方式,都能实现构造函数内部方法的创建,那么我们应该使用哪一种?

我们先来看下这两种方法的区别:

  • 函数内部直接声明,每声明一个实例,就会创建自己的函数副本,实例化时会增加内存消耗。
  • 挂载至原型,将方法挂载至构造函数的原型后,无论实例创建多少次,挂载在原型上的方法都只会创建一次,在所有实例中共享,可以节约内存和降低实例化的开销。

因此,在构造函数中声明方法,将其挂载至原型是最好的方案。

不过,将方法挂载至原型,该方法只能为public方法,而在构造函数内部声明的方法是private的。

写在最后

  • 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊
  • 本文首发于掘金,未经许可禁止转载💌
1

评论区