在浏览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
指向$)。这是怎么回事我的问题。有人可以在做什么时告诉我"返回新的$(选择器)",这会回到??
答案 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 $(...)
的值。这基本上是一个递归定义 - 虽然是递归的一个简单的例子,最多只能一次递归。有两个逻辑案例需要考虑。
$(...)
,则递归并返回new $(...)
的值。 return
是必需的,因为如果不使用undefined
,JavaScript函数默认返回return
。因此代码必须显式返回new ...
。new $(...)
(直接或通过保护条件中的那个简单的一步递归),那么我们正在处理一个实例。使用document.querySelectorAll
查找相应的节点,使用Array.prototype.push
将其加载到此实例中。在这种情况下,由于return
函数调用固有的神奇性,它总是返回创建的实例,因此不需要new
。因此,所有必要的是根据需要加载实例。它会自动返回。因此,典型用法如下:
$('p.main')
是最初的电话
$
函数检查并发现不没有处理实例,
所以递归,打电话给new $('p.main')
$
函数在第二个递归调用中正在处理实例。
它将DOM节点加载到此实例中,并隐式返回使用
new
的神奇特殊处理。
新实例返回原始调用的保护条件。
它必须明确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。这是对的吗?