不明白为什么需要返回声明

时间:2016-09-06 03:38:00

标签: javascript class constructor

在浏览javascript jquery $的javascript时,我不能理解为什么在这种情况下需要return

以下是我正在查看的代码

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

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

   };

有人可以向我解释为什么返回新的$(选择器)有效而不仅仅是新的$(选择器)?当你做一个回归时,你是否从一开始就使用new关键字开始整个过程​​?我很难想象这一点。请帮忙。

抱歉,如果我没有说清楚这一点。我的问题是声明&返回新的$(选择器)与新的$(选择器)有什么不同。当我在这个if语句中放置一个调试器并在this上放置一个观察器时,最初this是窗口,当我单步执行该函数时,我看到在运行return new $(selector)之后,它返回if语句,看看这是否是$的实例(因为现在this指向$)。这是怎么回事我的问题。有人可以在做什么时告诉我"返回新的$(选择器)",这会回到??

3 个答案:

答案 0 :(得分:3)

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

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

$ = function (selector) ...定义了对象的“类”行为。每次调用$(...)实例化一个新对象时,通过权限,您实际上需要调用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会立即结束初始$(...)来电,并返回new $(...)的值。这基本上是一个递归定义 - 虽然是递归的一个简单的例子,最多只能一次递归。有两个逻辑案例需要考虑。

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

    1. $('p.main')是最初的电话

    2. $函数检查并发现没有处理实例, 所以递归,打电话给new $('p.main')

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

    4. 新实例返回原始调用的保护条件。 它必须明确return该值,因为它最初是而不是 使用new,以便外部的原始调用享受new魔法 自动返回。它明确地返回新的 实例到原来的来电者。

答案 1 :(得分:1)

这是为了避免每当需要与您的方法进行交互时都需要new $("yourSelector")。行this instanceof $检查我们是否在函数的实例化版本中,而不仅仅是函数本身。

因此,如果(this instanceof $)false,我们需要通过执行return new $(selector)来实例化该函数。返回很重要,因为我们只是处于正常函数内部。这样,无论我们现在调用$函数的哪种方式,我们总会得到一个实例。

答案 2 :(得分:0)

我认为我对这件事情如此令人不安的是缺乏明确的官方文件(或者我无法找到它们或者我没有足够的研究(显然不是)。

我从以下的问答中找到了一个非常好的例子。

How does using a return clause before a recursive function call differ from not using one?

有这个例子:

function loop(x) {
  if (x >= 10) 
    return x;
  loop(x + 1); // the recursive call
}
loop(0);

用我裸露的未经训练的眼睛,看起来就像你在递归时,最终当x变为10时,它会向return x说。现在,我假设,这会返回它的调用者(循环(x + 1)??)。并且因为没有return语句,所以整个东西返回undefined。这是对的吗?

相关问题