ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript的函数

2021-09-19 14:33:24  阅读:146  来源: 互联网

标签:singleton return 函数 format JavaScript 参数 timeArr


ECMAScript中的函数实际上是对象。每个函数都是Function的实例,而Function也有属性和方法,和其他引用类型一样。函数是对象,函数名就是指向函数对象的指针,而且不一定与函数本身紧密绑定。

箭头函数

ESMAScript6新增了箭头函数,可以视为函数的简洁写法。
箭头函数和普通函数区别

  • argument
  • super
  • new.target
  • 不能用作构造函数
  • 没有prototype属性
  • this指向不同

函数名

函数名就是指向函数的指针。所以一个函数可以有多个名称。

ECMAScript6中所有的函数对象都会暴露一个只读属性name,包含关于函数的信息。

理解参数

ECMAScript函数的参数与大多数语言不同,不关心传入参数的个数,也不关心这些参数的类型,主要是因为ECMAScript函数的参数在内部表现为一个数组 arguments

箭头函数的参数:箭头函数没有arguments关键字来访问参数。

没有重载

ECMAScript函数没有签名,因为参数是由包含0个或多个值的数组表示,没有函数签名,自然也没有重载。

默认参数值

ECMAScript中没有给参数传值默认为undefined。也可以在写参数时设置默认值。

参数扩展和收集

使用扩展操作符(...),可以简洁的操作和组合集合数据。

函数声明与函数表达式

函数的声明提升:
JavaScript引擎在任何代码执行前,会先读取函数声明,并在执行上下文中生成函数定义;而函数表达必须等到执行到它那行,才会在执行上下文中生成函数定义。

函数内部

函数内部存在: argumentsthisnew.target 三个特殊的对象。

  • arguments 类数组对象,包含调用时传入的所有参数。
  • this 标准函数中,this引用的是把函数当成方法调用上下文对象。箭头函数中 this 是定义其的上下文。
  • caller 调用当前函数的函数。
  • new.target 是否使用new关键字调用的new.target属性。

函数属性与方法

函数是对象,因此有属性和方法。

属性

  • length 函数定义的命名参数的个数。
  • prototype 保存引用类型所有实例方法的地方。

方法

  • apply() 指定this调用函数。参数:函数内部this值、参数数组。
  • call() 指定this调用函数。参数:函数内部this值、参数1、参数2…。
  • bind() 指定this创建新的函数。参数:函数内部this值。

递归

递归函数 通常形式是一个函数通过函数名或arguments.callee调用自己。

function factorial(num) {
    if (num <= 1) {
        return 1
    }
    return num * factorial(num - 1);
}

尾递归优化

ES6尾调用优化的关键:如果函数的逻辑允许基于尾调用将其销毁,则引擎就会那么做。

尾调用优化的条件

尾调用优化的条件就是确认外部栈帧真的没必要存在了。

  • 代码在严格模式下执行。
  • 外部函数的返回值是对尾调用函数的调用。
  • 尾调用函数返回后不需要执行额外的逻辑。
  • 尾调用函数不是引用外部函数作用域中自由变量的闭包。

尾调用优化的代码

主要是调整参数,将变动的值通过参数传递到递归函数。

闭包

引用了另一个函数作用域中变量的函数,通常在嵌套函数中实现。

this对象

闭包时使用箭头函数,可以避免一些this产生的问题。

内存泄露

IEIE9之前对JScript对象和COM对象使用了不同的垃圾回收机制,闭包在旧版IE中可能会导致一些问题。
解决办法:解除对对象的引用。

立即调用的函数表达式

立即调用的匿名函数被称为立即调用的函数表达式(IIFE)

(function () {
    // 函数体
})();

私有变量

JavaScript没有私有成员的概念,所有的对象属性都是公有的。不过有私有变量的概念,私有变量包括函数参数、局部变量,以及函数内部定义的其他函数。

静态私有变量

特权方法也可以使用私有作用域定义私有变量和函数实现。


const Person = (function () {
    let name = "";

    return class Person {
        constructor() {

        }

        getName() {
            return name;
        }

        setName(val) {
            name = val;
        }
    };
})();

let p1 = new Person();
p1.setName("name");
console.log(p1.getName());

模块模式

在一个单例对象上实现了相同的隔离和封装。Web开发中,使用单例对象管理程序级的信息。

const singleton = (function () {
    const arr = [];

    return {
        getArrCount() {
            return arr.length
        },
        addItem(item) {
            arr.push(item);
        },
        write() {
            return JSON.stringify(arr);
        }
    }
})();

singleton.addItem("1");
singleton.addItem("2");
singleton.addItem("3");

console.log(singleton.getArrCount());
console.log(singleton.write());

模块增强模式

另一个利用模块模式的做法时在返回对象之前对其进行增强,适用于单例对象需要是某个特定类型的实例单又必须给它添加额外的属性或方法的场景。


const singleton = (function () {
    let curTime = null;
    const timeArr = [];

    timeArr.now = function () {
        curTime = new Date();
        timeArr.push(curTime);
        return curTime;
    }

    timeArr.format = function (format, time = curTime) {
        if (!time) {
            return undefined;
        }
        const o = {
            "M+": time.getMonth() + 1,                 //月份
            "d+": time.getDate(),                    //日
            "h+": time.getHours(),                   //小时
            "m+": time.getMinutes(),                 //分
            "s+": time.getSeconds(),                 //秒
            "q+": Math.floor((time.getMonth() + 3) / 3), //季度
            "S": time.getMilliseconds()             //毫秒
        };
        if (/(y+)/.test(format))
            format = format.replace(RegExp.$1, (time.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (const k in o)
            if (new RegExp("(" + k + ")").test(format))
                format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return format;
    }
    timeArr.clear = function () {
        timeArr.splice(0, timeArr.length);
        curTime = null;
    }
    timeArr.getTimes = function () {
        console.log(timeArr)
    }
    timeArr.size = function () {
        return timeArr.length;
    }
    return timeArr;
})();

const t1 = singleton.now();
console.log(singleton.format("yyyy mm:ss S"));
const t2 = singleton.now();
console.log(singleton.format("yyyy mm:ss S"));
console.log(singleton.format("yyyy mm:ss S", t1));
console.log(singleton.size());
singleton.clear();
console.log(singleton.size());

标签:singleton,return,函数,format,JavaScript,参数,timeArr
来源: https://blog.csdn.net/weixin_44589858/article/details/120380265

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有