• 《JavaScript Ninja》之函数是根基


    函数是根基

    理解函数为什么如此重要

    JavaScript 是一门 函数式语言

    函数为什么是第一型对象

    在 JavaScript 中,函数可以共处,可以将其视为其他任意类型的 JavaScript 对象而进行使用,除此之外,函数还有一个特殊的功能,它们可以 被调用(通常以 异步方式 进行调用)。

    对象在 JavaScript 中有如下功能:

    • 它们可以通过字面量创建。
    • 它们可以赋值给变量、数组或其他对象的属性。
    • 它们可以作为参数传递。
    • 它们可以作为函数的返回值进行返回。
    • 它们拥有动态创建并赋值的属性。

    浏览器如何调用函数

    1. 我们为浏览器中发生的各种事件建立事件处理程序,这些事件在触发时被放置在一个事件队列中(先进先出列表[FIFO]);

    2. 浏览器负责事件轮询和事件派发,从而调用我们事先建立好的事件处理程序。

    注意:

    • 浏览器的事件轮询是 单线程 的。每个事件都是按照在队列中所放置的顺序来处理的。
    • 浏览器把事件放到队列上的机制是在事件轮询模型之外。确定事件何时发生并把它们放到事件队列上的过程所处的线程,并不参与事件本身的处理。

    回调:我们定义一个函数,以便其他一些代码在适当的时机回头再调用它。

    函数声明

    JavaScript 函数是使用 函数字面量 进行声明从而创建函数值的。

    函数字面量由四个部分组成:

    1. function 关键字
    1. 可选名称,如果指定名称,则必须是一个有效的 javaScript 标识符;
    1. 括号内部,一个以逗号分隔的参数列表。(有效的标识符,参数列表允许为空,圆括号必须始终存在);
    1. 函数体,包含在大括号内的一系列 JavaScript 语句。(函数体可以为空,但大括号必须始终存在)。

    命名一个函数时,该名称在整个函数声明范围内是有效的。此外,如果一个命名函数声明在顶层,window 对象上的同名属性则会引用到该函数。

    所有的函数都有一个 name 属性,该属性保存的是该函数名称的字符串。没有名称的函数也仍然有 name 属性,只是该属性值为空字符串罢了。

    作用域和函数

    • 变量声明的作用域开始于声明的地方,结束于所在函数的结尾,与代码嵌套无关。
    • 命名函数的作用域是指声明该函数的整个函数范围,与代码嵌套无关。(有些人称之为 机制提升。)
    • 对于作用域声明,全局上下文就像一个包含页面所有代码的超大型函数。

    函数可以在其作用域范围内提前被引用,而变量不行。

    参数赋值之谜

    函数调用的四种方式:

    • 作为一个函数 进行调用(最简单形式);
    • 作为一个方法 进行调用,在对象上进行调用,支持面向对象编程;
    • 作为构造器 进行调用,创建一个新对象;
    • 通过 apply() 或 call() 方法 进行调用(较复杂)。

    从参数到函数形参

    • 如果实际传递的参数大于函数声明的形参数量,超出的参数则不会配给形参名称;

    • 如果声明的形参数量大于实际传递的参数数量,则没有对应参数的形参会赋值为 undefined

    所有的函数调用都会传递两个隐式参数argumentsthis

    所谓 隐式 : 意味着这些参数不会显示列在函数签名里,而会默默地传递给函数并存在于函数作用域内。在函数内部,可以像其他显示命名的参数一样使用。

    arguments 参数

    传递给函数的所有参数的一个集合,有 length 属性。只是一个类数组结构,并且只拥有数组的某些特性。

    this 参数

    this 参数引用了与该函数进行隐式关联的一个对象,被称之为 函数上下文

    JavaScript 中的 this 依赖于函数的调用方式,可以称为 调用上下文

    (1)作为函数进行调用:

    • 此时,函数的上下文是全局上下文——window对象,并没有把函数作为对象的一个属性,通常被认为是自己的机制。

    (2)作为对象的方法进行调用:

    • 此时,该对象就变成了函数上下文,并且在函数内部可以以 this 参数的形式进行访问。

    • 与“作为函数”进行调用对比:除了“作为函数”进行调用是定义在 window 上的,而且调用的时候不必再需要 window 的一个引用了。其它是一样的,函数“属于” window,window 则作为函数上下文,和对象 o 作为函数上下文是一样的道理。

    (3)作为构造器进行调用:

    • 此时,要在函数调用前使用 new 关键字。

    构造器的超能力:

    • 创建一个新的空对象;
    • 传递给构造器的对象是 this 参数,从而成为构造器的函数上下文;
    • 如果没有显式的返回值,新创建的对象则作为构造器的返回值进行返回。

    构造器的目的 : 要创建一个新对象并对其进行设置,然后将其作为构造器的返回值进行返回。

    至此,我们看到,函数调用方式之间的 主要差异 是:作为 this 参数传递给执行函数的上下文对象之间的区别。作为方法进行调用,该上下文是方法的拥有者;作为全局函数进行调用,其上下文永远是 window(也就是说,该函数是 window 的一个方法);作为构造器进行调用,其上下文对象则是新创建的对象实例。

    (4)使用 apply() 或 call() 方法进行调用:

    • 在函数调用时,可以显式指定任何一个对象作为其函数上下文。

    • 实际使用时,选择最能匹配参数的那个方法。

    函数上下文

    • 函数是程序的构建块而不是命令式语句。

    可以用不同的方法进行函数调用,不同的调用机制决定了函数上下文的不同。

    作为普通函数进行调用时,其上下文是全局对象(window)。

    作为方法进行调用时,其上下文是拥有该对象的方法。

    作为构造器进行调用时,其上下文是一个新分配的对象。

    通过函数的 apply() 或 call() 方法进行调用时,上下文可以设置成任意值。

    Scoop It and Enjoy the Ride!
  • 相关阅读:
    Python循环-break和continue
    Python-SocketServer
    Python模块-datetime模块
    Python模块-time模块
    dataframe转化(一)之python中的apply(),applymap(),map() 的用法和区别
    python面试题--连续出现最大次数
    消金ABS
    《风控策略笔记》(二)政策与定价--量化风险管理应用
    hadoop fs –stat 命令
    《风控策略笔记》(一)政策与定价--风控体系及政策设计
  • 原文地址:https://www.cnblogs.com/Ruth92/p/5468816.html
Copyright © 2020-2023  润新知