javascript - 不明白为什么需要return语句

标签 javascript class constructor

在研究 javascript 模拟 jquery $ 时,我无法理解为什么在这种情况下需要 return

这是我正在查看的代码

   $ = function(selector){ 
          if ( !(this instanceof $) ) {
              return new $(selector);
          }
      var elements = document.querySelectorAll(selector); 

      Array.prototype.push.apply(this,elements);

   };

有人可以向我解释一下为什么 return new $(selector) 有效,而不仅仅是 new $(selector) 吗?当你进行返回时,你是否使用 new 关键字从头开始整个事情?我很难想象这一点。请帮忙。

抱歉,如果我没有说清楚。我的问题是“return new $(selector)”语句与 new $(selector) 的作用有何不同。当我将调试器放在这个 if 语句中并在 this 上放置一个观察器时,最初 this 是窗口,当我单步执行该函数时,我看到在运行 return 后new $(selector),它返回到 if 语句来查看 this 是否是 $ 的实例(因为现在 this 指向 $)。我的问题是怎么发生的。有人可以告诉我在执行“return new $(selector)”时,它返回到哪里吗?

最佳答案

这是一种常见的 JavaScript 习惯用法,可确保您处理的是实例对象而不是类对象。

(从技术上讲,JavaScript 是一个基于原型(prototype)的对象系统,但类/实例的区别是描述这种关系的最常见/最容易识别的隐喻。)

$ = 函数(选择器)... 定义对象“类”的行为方式。按理说,每次调用 $(...) 实例化一个新对象时,实际上都需要调用 new $(...) 来返回一个新对象类的实例。 $(...) 不仅仅是一个函数调用;从本质上讲,它是一个构造函数。它定义了如何形成类的新实例。这个小小的 instanceof 测试和 return new $(selector) 正在自动执行所需的 new ——这是非常容易忘记的事情,实际上通常是惯用的不使用。保护条件就在那里,因此您不必必须手动调用new

$ = function(selector) { 
      if ( !(this instanceof $) ) {
          // if was called naked, without new, auto-new an instance
          return new $(selector);
      }
    // by time execution arrives here, we have guaranteed that we are
    // dealing with an instance of $, not $ itself (i.e. an instance not
    // the class)
    var elements = document.querySelectorAll(selector); 

    // use Array class to make this instance an array-like
    // object holding the selected DOM elements
    Array.prototype.push.apply(this,elements);
  };

更新/说明 保护条件内的 return 立即结束初始 $(...) 调用,返回 新$(...)。这基本上是一种递归定义——尽管这是一种微不足道的递归情况,最多只能递归一次。有两种逻辑情况需要考虑。

  1. 如果调用$(...),则递归并返回new $(...)的值。 return 是必需的,因为如果没有使用 return,JavaScript 函数默认返回 undefined。因此代码必须显式返回 new ... 的值。
  2. 如果 new $(...) 被调用(直接调用,或者通过保护条件的简单单步递归),那么我们正在处理一个实例。使用 document.querySelectorAll 查找适当的节点,并使用 Array.prototype.push 将它们加载到此实例中。在这种情况下,不需要返回,因为 new 函数调用固有的魔力,它总是返回创建的实例。因此,所需要做的就是根据需要加载实例。它将自动返回。

因此,典型的用法如下:

  1. $('p.main') 是原始调用

  2. $ 函数检查并发现它not不处理实例, 所以递归,调用 new $('p.main')

  3. 第二个递归调用中的
  4. $ 函数现在正在处理一个实例。 它将 DOM 节点加载到此实例中,并使用隐式返回 new 的神奇特殊处理。

  5. 新实例返回到原始调用的保护条件。 它必须显式返回该值,因为它最初不是被调用的 使用 new,因此外部原始调用不会享受 new 魔力 自动返回。它明确返回新的 原始调用者的实例。

关于javascript - 不明白为什么需要return语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39340278/

相关文章:

javascript - 带下划线或条件的下划线(下划线、lodash 或任何其他解决方案)

javascript - 从链接菜单中单击链接时发布变量

c++ - 无论如何,在 c++ 中是否有一个类的函数,每个类的对象都为该函数做不同的事情?

Javascript 使用 constructor.prototype 访问父类(super class)成员失败?

java - 尝试创建一个带有 2D vector 和字符串数组头的 JTable,我该怎么做?

c# - 在 C# 中,从构造函数调用虚方法是否安全?

javascript - 点击 Google map 标记时添加信息窗口气泡

javascript - 三.js多重效果图

wpf - VS2010 : Error in Adding Reference of Project 1 into Project 2 and Vice Versa

c# - C#中的父子继承管理