天道酬勤,学无止境

有什么快速的方法可以得到从一个按值,使用 JavaScript?(Is there any fast way to get an <option> from a <select> by value, using JavaScript?)

问题

我有一个 <select>。 使用 JavaScript,我需要从选项列表中获取特定的 <option>,而我所知道的只是该选项的值。 该选项可能会或可能不会被选中。

这里有一个问题:有成千上万个选项,我需要循环执行几百次。 现在我遍历“选项”数组并寻找我想要的选项。 这太慢了(从某种意义上说,在我非常快的机器上,浏览器锁定,直到我在几分钟后将其杀死)。

有没有更快的方法来做到这一点? 我将采用特定于浏览器的方式,但当然 DOM 标准方式会很好。

回答1

我会这样做:

// first, build a reverse lookup
var optCount      = mySelect.options.length;
var reverseLookup = {};
for (var i = 0; i < optCount; i++)
{
  var option = mySelect.options[i];
  if (!reverseLookup[option.value])
  {
    // use an array to account for multiple options with the same value
    reverseLookup[option.value] = [];
  }
  // store a reference to the DOM element
  reverseLookup[option.value].push(option);
}

// then, use it to find the option
var foundOptions = reverseLookup["Value that you are looking for"];
if (foundOptions && foundOptions.length)
{
  alert(foundOptions[0].id);
}
回答2

我建议您的选择中不要有数千个选项。

也许你可以用不同的方式构建你的数据,一个包含数千个条目的选择对我来说似乎是错误的。

也许您的应用程序需要这个,但它不会是这个元素的典型用法。

回答3

这是 Tomalak 的答案,稍微调整了速度。 您会看到向下迭代的 while 循环比向上迭代的 for 循环快。 (我很懒,所以我不会提供链接。)

var i = mySelect.options.length - 1;
var reverseLookup = {};
while ( i >= 0 )
{
  var option = mySelect.options[i];
  if (!reverseLookup[option.value])
  {
    // use an array to account for multiple options with the same value
    reverseLookup[option.value] = [];
  }
  // store a reference to the DOM element
  reverseLookup[option.value].push(option);
  i--;
}

// then, use it to find the option
var foundOptions = reverseLookup["Value that you are looking for"];
if (foundOptions && foundOptions.length)
{
  alert(foundOptions[0].id);
}
回答4

不,没有,您正在以最好的方式做这件事。 唯一可以尝试更快查找的另一件事是为每个选项提供一个 ID 标签,以便您可以将它们作为 DOM 对象进行查找,而不是遍历 DOM 对象的子对象。

回答5

您可以一次遍历所有选项并将所有项目放入关联数组中。 然后你可以只查找myOptions[valueImLookingFor]

我没有测试过这个,不能保证它会更快/更好。 但它应该摆脱所有这些循环。

根据您的设置和需要,您还可以在客户端生成一个 javascript 数组并将其放在标记中而不是(或除了)选择。

回答6

我的建议是查看像 Dojo 这样的框架/工具包及其选择 DOM 节点的方式。

该工具包消除了许多浏览器不一致的问题,并允许您快速轻松地选择和操作 DOM 节点。

回答7

我认为这可能表明选择中的“数千”项可能不是最佳的用户体验。 也许您应该考虑尝试将下拉列表限制为几个,以便在用户选择它们时缩小结果范围。

回答8

使用jQuery,这样的事情可能会更快:

$("#idselect option[value='yourval']")

http://docs.jquery.com/Selectors/attributeEquals#attributevalue

标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 适用于快速获取和快速删除的 Java 集合(Suitable java collection for fast get and fast removal)
    问题 我想知道是否有适合“快速”获取(按索引)和“快速”删除的 Java 接口。 “快”是指比O(n) 。 编辑:只有从集合中随机选择一个元素时才需要 get 方法。 此外,标题应该说“集合”而不是“界面”。 回答1 平衡二叉搜索树具有 O(log n) 次“获取”和“删除”操作。 哈希表在 O(1) 时间内实现这些相同的操作。 在 Java 中,您可以使用 TreeMap 或 HashMap 类。 例如: TreeMap<Integer, String> map = new TreeMap<>(); map.put(0, "hello"); map.put(1, "world"); map.remove(0); 如果您不关心项目的顺序,则可以使用ArrayList 。 自然地“得到”是 O(1)。 要删除一个项目,将最后一个项目移动到您删除的项目的位置,这会给您一个 O(1) 的“删除”。 那是: temp = list.remove(list.size()-1); return list.set(index, temp); 回答2 我不确定我是否理解您建议如何推断您想要从哪个索引获取对象。 如果您正在寻找快速 get() 和快速 remove() 操作 - 标准HashMap<Object, Object>有什么问题(即使用对象本身作为键)? 那么你的 get()/remove
  • 在Java中按值从Map中删除元素的最快方法是什么?(What's the quickest way to remove an element from a Map by value in Java?)
    问题 在Java中按值从Map中删除元素的最快方法是什么? 目前,我正在使用: DomainObj valueToRemove = new DomainObj(); String removalKey = null; for (Map.Entry<String, DomainObj> entry : map.entrySet()) { if (valueToRemove.equals(entry.getValue())) { removalKey = entry.getKey(); break; } } if (removalKey != null) { map.remove(removalKey); } 回答1 无需使用双向地图(公共收藏夹和Google收藏夹都有它们),您就无法遍历该地图 回答2 正确和快速的一线实际上是: while (map.values().remove(valueObject)); 奇怪的是,上面的大多数示例都假定valueObject是唯一的。 回答3 这是一线解决方案: map.values().remove(valueToRemove); 这可能比定义自己的迭代器要快,因为JDK集合代码已得到了极大地优化。 正如其他人提到的那样,尽管bimap需要更多的内存并且需要更长的填充时间,但其移除值的速度更快。 另外,仅当值唯一时,bimap才起作用
  • 按值和条件分组(Group by values and conditions)
    问题 对 mongo 非常陌生,在解决这个问题时遇到了一些麻烦。 我有看起来像这样的收藏 { "_id" : "PN89dNYYkBBmab3uH", "card_id" : 1, "vote" : 1, "time" : 1437700845154 } { "_id" : "Ldz7N5syeW2SXtQzP", "card_id" : 1, "vote" : 1, "time" : 1437700846035 } { "_id" : "v3XWHHvFSHwYxxk6H", "card_id" : 1, "vote" : 2, "time" : 1437700849817 } { "_id" : "eehcDaCyTdz6Yd2a9", "card_id" : 2, "vote" : 1, "time" : 1437700850666 } { "_id" : "efhcDaCyTdz6Yd2b9", "card_id" : 2, "vote" : 1, "time" : 1437700850666 } { "_id" : "efhcDaCyTdz7Yd2b9", "card_id" : 3, "vote" : 1, "time" : 1437700850666 } { "_id" : "w3XWgHvFSHwYxxk6H", "card_id" : 1, "vote" : 1
  • 按值复制数组(Copy array by value)
    问题 将JavaScript中的数组复制到另一个数组时: var arr1 = ['a','b','c']; var arr2 = arr1; arr2.push('d'); //Now, arr1 = ['a','b','c','d'] 我意识到arr2指向与arr1相同的数组,而不是一个新的独立数组。 如何复制阵列以得到两个独立的阵列? 回答1 用这个: let oldArray = [1, 2, 3, 4, 5]; let newArray = oldArray.slice(); console.log({newArray}); 基本上,slice()操作将克隆该数组并返回对新数组的引用。 另请注意: 对于引用,字符串和数字(​​而不是实际对象), slice()对象引用复制到新数组中。 原始数组和新数组都引用同一对象。 如果引用的对象发生更改,则更改对新数组和原始数组都是可见的。 字符串和数字之类的基元是不可变的,因此无法更改字符串或数字。 回答2 在Javascript中,深层复制技术取决于数组中的元素。 让我们从这里开始。 三种类型的元素 元素可以是:文字值,文字结构或原型。 // Literal values (type1) const booleanLiteral = true; const numberLiteral = 1; const
  • 使用ASP.Net MVC与Web表单的最大优势(Biggest advantage to using ASP.Net MVC vs web forms)
    问题 已锁定。 该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。 它目前不接受新的答案或互动。 与另一种相比,使用一种有什么优势? 回答1 ASP.net MVC的主要优点是: 启用对呈现的HTML的完全控制。 提供关注点的清晰分离(SoC)。 启用测试驱动开发(TDD)。 易于与JavaScript框架集成。 遵循网络无状态性质的设计。 启用S​​EO的RESTful网址。 没有ViewState和PostBack事件 ASP.net Web窗体的主要优点是: 它提供RAD开发适用于来自winform开发的开发人员的简易开发模型。 回答2 ASP.NET Web窗体和MVC是Microsoft开发的两个Web框架-它们都是不错的选择。 这两个Web框架都不能被另一个替代,也没有计划将它们“合并”为一个框架。 Microsoft会同时进行持续的支持和开发,而且两者都不会“消失”。 这些Web框架中的每一个都有优点/缺点-开发Web应用程序时需要考虑其中的一些优点/缺点。 可以使用任何一种技术来开发Web应用程序-它可能使针对特定应用程序的开发更容易选择一项技术,而选择另一项则相反。 ASP.NET Web表单: 开发支持状态•与Windows应用程序类似,给人一种Web应用程序意识到用户正在做的事情的错觉。 即使“向导”功能更易于实现。
  • 按引用传递与按值传递有什么区别?(What's the difference between passing by reference vs. passing by value?)
    问题 之间有什么区别 通过引用传递的参数通过值传递的参数? 请给我一些例子吗? 回答1 首先,在CS理论中定义的“按值传递与按引用传递”的区别现在已过时,因为最初定义为“按引用传递”的技术此后不再受欢迎,现在很少使用。 1个 较新的语言2倾向于使用不同的(但相似的)技术对来达到相同的效果(见下文),这是造成混淆的主要原因。 造成混淆的第二个原因是,在“通过引用传递”中,“引用”的含义比通用术语“引用”的含义要窄(因为该短语早于它)。 现在,真实的定义是: 通过引用传递参数时,调用者和被调用者对该参数使用相同的变量。 如果被调用方修改了参数变量,则效果对调用方的变量可见。 通过value传递参数时,调用方和被调用方将具有两个具有相同值的独立变量。 如果被调用方修改了参数变量,则该效果对调用方不可见。 在此定义中要注意的是: 这里的“变量”是指调用方的(本地或全局)变量本身-即,如果我通过引用传递局部变量并将其分配给它,则我将更改调用方的变量本身,而不是例如它是指针时指向的变量。 现在,这被认为是不好的做法(作为隐式依赖)。 因此,几乎所有较新的语言都是专有的或几乎专有的值传递。 现在,在函数不能返回多个值的语言中,按引用传递主要以“输出/输入参数”的形式使用。 “通过引用传递”中“引用”的含义。 与一般“参考”一词的区别在于,该“参考”是暂时的和隐含的。 被呼叫者基本上得到的是一个
  • 将const std :: string&作为参数传递的日子已经过去了吗?(Are the days of passing const std::string & as a parameter over?)
    问题 我听过Herb Sutter最近的一次演讲,他提出通过const &传递std::vector和std::string的原因已基本消失。 他建议现在编写一个如下所示的函数是更可取的: std::string do_something ( std::string inval ) { std::string return_val; // ... do stuff ... return return_val; } 我知道return_val在函数返回时将是一个右值,因此可以使用移动语义返回,这非常便宜。 但是, inval仍然比引用(通常实现为指针)的大小大得多。 这是因为std::string具有各种组件,包括指向堆的指针和用于短字符串优化的成员char[] 。 因此在我看来,通过引用传递仍然是一个好主意。 谁能解释为什么Herb可能会这么说? 回答1 赫伯之所以说他的话,是因为这样的情况。 假设我有A函数B ,该函数调用函数B ,该函数调用函数C A将字符串通过B传递到C A不知道或不在乎C ; A知道B 也就是说, C是B的实现细节。 假设A定义如下: void A() { B("value"); } 如果B和C通过const&接受字符串,则它看起来像这样: void B(const std::string &str) { C(str); } void C(const std
  • 在 C# 中按值传递引用类型(Passing Reference types by value in C#)
    问题 我想将引用类型按值传递给 C# 中的方法。 有没有办法做到这一点。 在 C++ 中,如果我想通过 Value 传递,我总是可以依靠复制构造函数来发挥作用。 除了:1. 显式创建一个新对象 2. 实现 IClonable 然后调用 Clone 方法之外,在 C# 中有什么方法。 这是一个小例子: 让我们以 C++ 中的类 A 为例,它实现了一个复制构造函数。 一个方法func1(Class a),我可以通过说func1(objA)来调用它(自动创建一个副本) C#中是否存在类似的东西。 顺便说一下,我使用的是 Visual Studio 2005。 回答1 不,C# 中没有等效的复制构造函数。 你传递的(按值)是一个引用。 ICloneable也有风险,因为它是深还是浅的定义很差(而且它没有得到很好的支持)。 另一种选择是使用序列化,但同样,它可以快速绘制比您预期的多得多的数据。 如果担心您不希望方法进行更改,则可以考虑使类不可变。 那么没有人可以对它做任何讨厌的事情。 回答2 正如已经解释过的,没有等同于 C++ 的复制构造函数。 另一种技术是使用对象不可变的设计。 对于不可变对象,传递引用和副本之间没有(语义)差异。 这就是 System.String 的设计方式。 其他系统(特别是函数式语言)更多地应用这种技术。 回答3 根据此链接(已发布):http://msdn
  • 在python中按值删除字典项的最佳方法是什么? [复制](What is the best way to remove a dictionary item by value in python? [duplicate])
    问题 这个问题已经在这里有了答案: 根据值从字典中删除条目(4个答案) 1年前关闭。 我想知道是否有一种简单的方法可以通过value从python字典中删除一个或多个字典元素。 我们有一个名为myDict的字典: myDict = {1:"egg", "Answer":42, 8:14, "foo":42} 并要删除所有值等于42 。 实施建议: 获取myDict某个值的所有键的列表 (例如,参见在字典中按值获取密钥。) 从myDict删除此dict元素或多个元素(基于找到的键) (有关更多信息,请参阅从字典中删除元素。) 那么,您认为现在在Python中实现此问题的最优雅,最“ Python式”的方式是什么? 回答1 您可以使用简单的dict理解: myDict = {key:val for key, val in myDict.items() if val != 42} 因此: >>> {key:val for key, val in myDict.items() if val != 42} {8: 14, 1: 'egg'} 回答2 您必须创建一个副本以进行迭代,因为在循环内更改字典的大小会导致RunTimeError。 使用items()遍历字典副本中的键,值对,并将每个值与所需的值进行比较。 如果它们匹配,请从字典中删除密钥。 for key, value in dict
  • 为什么C ++不支持函数返回数组?(Why doesn't C++ support functions returning arrays?)
    问题 某些语言使您能够像正常函数一样声明一个函数,该函数返回一个数组,例如Java: public String[] funcarray() { String[] test = new String[]{"hi", "hello"}; return test; } 为什么C ++不支持int[] funcarray(){} ? 您可以返回一个数组,但是创建这样的函数确实很麻烦。 而且,我在某处听说字符串只是char的数组。 因此,如果您可以用C ++返回一个字符串,为什么不使用数组呢? 回答1 简而言之,我猜这只是一个设计决定。 更具体地说,如果您真的想知道为什么,则需要从头开始。 让我们首先考虑一下C。 在C语言中,“按引用传递”和“按值传递”之间有明显的区别。 简单地说,C语言中的数组名称实际上只是一个指针。 对于所有意图和目的,区别(通常)归结为分配。 代码 int array[n]; 会在堆栈上创建4 * n字节的内存(在32位系统上),并且与声明该代码块的范围相关。 反过来, int* array = (int*) malloc(sizeof(int)*n); 将创建相同数量的内存,但是在堆上。 在这种情况下,内存中的内容与范围无关,只有对内存的引用受范围的限制。 这就是按值传递和按引用传递的地方。如您所知,按值传递意味着将某些内容传递给函数或从函数返回时,传递的“事物
  • JavaScript是按引用传递还是按值传递语言?(Is JavaScript a pass-by-reference or pass-by-value language?)
    问题 基本类型(数字,字符串等)按值传递,但是对象是未知的,因为它们都可以按值传递(如果我们认为保存对象的变量实际上是对该对象的引用) )和按引用传递(当我们认为对象的变量包含对象本身时)。 尽管最后并没有什么大不了,但我想知道什么是表达通过约定的参数的正确方法。 是否有JavaScript规范的摘录,该摘录定义了与此相关的语义? 回答1 在JavaScript中这很有趣。 考虑以下示例: function changeStuff(a, b, c) { a = a * 10; b.item = "changed"; c = {item: "changed"}; } var num = 10; var obj1 = {item: "unchanged"}; var obj2 = {item: "unchanged"}; changeStuff(num, obj1, obj2); console.log(num); console.log(obj1.item); console.log(obj2.item); 产生输出: 10 changed unchanged 如果obj1根本不是引用,则更改obj1.item对该函数外部的obj1无效。 如果论点是一个适当的参考,那么一切都会改变。 num为100 ,而obj2.item读为"changed" 。 相反,情况是传入的项目是按值传递的
  • 顶级const不会影响函数签名(Top-level const doesn't influence a function signature)
    问题 在C ++ Primer 5th Edition中,它表示: int f(int){ /* can write to parameter */} int f(const int){ /* cannot write to parameter */} 这两个功能是无法区分的。 但是,正如您所知,这两个函数在更新参数方面的方式确实有所不同。 有人可以向我解释吗? 编辑我想我的问题解释得不好。 我真正关心的是为什么C ++不允许这两个函数同时作为不同的函数使用,因为它们在“是否可以写入参数”方面确实有所不同。 凭直觉,应该! 编辑按值传递的性质实际上是通过将参数值复制到参数值来传递的。 即使对于引用和指针,其中复制的值是地址。 从调用者的角度来看,将const或非const传递给函数均不会影响复制到参数的值(当然还有其类型)。 复制对象时,顶级常量和低级别的常量之间的区别很重要。 更具体地说,由于复制不会影响复制的对象复制对象时顶层常量(未低电平常量的情况下)将被忽略。 复制到对象或从对象复制的对象是否为const无关紧要。 因此,对于呼叫者,不必区分它们。 从函数的角度来看,顶级const参数可能不会影响函数的接口和/或功能。 这两个功能实际上完成了同一件事。 为什么要麻烦实施两个副本? 回答1 允许这两个函数同时作为不同的函数使用,因为它们在“是否可以写入参数”方面确实有所不同。
  • 2020前端进阶面试题
    一、JavaScript基础 前端工程师吃饭的家伙,深度、广度一样都不能差。 变量和类型 JavaScript规定了几种语言类型 JavaScript中的每一个值都有它自己的类型,JavaScript规定了七种语言类型: 1.Undefined 2.Null 3.Boolean 4.String 5.Number 6.Symbol 7.Object JavaScript对象的底层数据结构是什么 Symbol类型在实际开发中的应用、可手动实现一个简单的 Symbol JavaScript中的变量在内存中的具体存储形式 栈内存和堆内存 JavaScript中的变量分为基本类型和引用类型 基本类型是保存在栈内存中的简单数据段,它们的值都有固定的大小,保存在栈空 间,通过按值访问 引用类型是保存在堆内存中的对象,值大小不固定,栈内存中存放的该对象的访问地 址指向堆内存中的对象,JavaScript不允许直接访问堆内存中的位置,因此操作对象时,实际操作对象的引用 5.基本类型对应的内置对象,以及他们之间的装箱拆箱操作 在《javascript高级程序设计》中有这样一句话: 每当读取一个基本类型的时候,后台就会创建一个对应的基本包装类型对象,从而让我们能够调用一些方法来操作这些数据。(隐式装箱) 隐式装箱 let a = 'sun' let b = a.indexof('s') // 0 //
  • 何时使用Vanilla JavaScript vs.jQuery?(When to use Vanilla JavaScript vs. jQuery?)
    问题 我注意到在监视/尝试回答常见的jQuery问题时,有一些使用javascript(而不是jQuery)的实践实际上使您可以编写更少的代码,并且做得...数量相同。 并且还可能产生性能优势。 一个具体的例子 $(this) vs this 在点击事件内部,该事件引用被点击的对象ID jQuery的 $(this).attr("id"); Java脚本 this.id; 还有其他类似的常规做法吗? 在不将jQuery混用的情况下,某些Javascript操作可以更轻松地完成的地方。 还是这是罕见的情况? (实际上是需要更多代码的jQuery“快捷方式”) 编辑:虽然我很欣赏有关jQuery与普通javascript性能的答案,但实际上我正在寻找更多定量的答案。 在使用jQuery时,使用普通javascript而不是使用$()实际上会更好(可读性/紧凑性)的实例。 除了我在原始问题中给出的示例之外。 回答1 this.id (如您所知) this.value (在大多数输入类型上。当<select>的<option>元素或Safari中的单选输入没有设置value属性时,我知道的唯一问题就是IE。) this.className获取或设置整个“ class”属性 this.selectedIndex对于<select>以获得选定的索引针对<select> this
  • PHP“ foreach”实际上如何工作?(How does PHP 'foreach' actually work?)
    问题 首先,我要说一下我知道foreach是什么,做什么以及如何使用它。 这个问题关系到它如何在引擎盖下工作,我不希望“这就是使用foreach循环数组的方式”的答案。 很长时间以来,我一直认为foreach与数组本身一起工作。 然后,我发现了很多关于它可以与数组副本一起使用的事实的引用,从那时起,我一直以为这是故事的结尾。 但是我最近对此事进行了讨论,经过一番实验后发现这实际上并非100%正确。 让我表明我的意思。 对于以下测试用例,我们将使用以下数组: $array = array(1, 2, 3, 4, 5); 测试用例1: foreach ($array as $item) { echo "$item\n"; $array[] = $item; } print_r($array); /* Output in loop: 1 2 3 4 5 $array after loop: 1 2 3 4 5 1 2 3 4 5 */ 这清楚地表明,我们不是直接使用源数组-否则循环将永远持续下去,因为我们在循环过程中不断将项目推入数组。 但是只是为了确保是这种情况: 测试案例2: foreach ($array as $key => $item) { $array[$key + 1] = $item + 2; echo "$item\n"; } print_r($array); /*
  • Ruby 是按值传递还是按引用传递? [复制](Is Ruby pass-by-value or pass-by-reference? [duplicate])
    问题 这个问题在这里已经有了答案: Ruby 是按引用传递还是按值传递? (14 个回答) 6年前关闭。 我基本上是一个java开发人员。 我在 ruby​​ 工作了大约一年。 与 java 不同,Ruby 是一种纯面向对象的编程语言。 一个疑问来了。 它是按值传递还是按引用传递? Java 作为传值工作:“当传递原语时,我看到值被复制并传递给方法。但在对象的情况下,引用被复制并传递给方法。引用包含对象的位置在堆中。在方法调用期间,只传递对象的位置。因此不会创建重复的对象。修改相同的对象。” 但是当我尝试下面的 ruby​​ 代码片段时,我得到了与在 Java 中得到的结果相同的结果:“在方法调用期间,数字像原始数据一样工作(就像在 Java 中一样),而数组像在 Java 中一样作为完美引用工作”。 现在,我很困惑。 如果 ruby​​ 中的所有内容都是对象,那么为什么在方法调用期间会重复编号对象? class A def meth1(a) a = a+5 puts "a inside meth1---#{a}" end def meth2(array) array.pop puts "array inside meth2---#{array}" end end obj1 = A.new aa=5 obj1.meth1(aa) puts "aa-----#{aa}" arr =
  • 为什么选择结构而不是课堂?(Why Choose Struct Over Class?)
    问题 在Java背景下玩Swift,为什么要选择Struct而不是Class? 似乎它们是同一回事,但Struct提供的功能较少。 那为什么选择它呢? 回答1 根据非常流行的WWDC 2015演讲中的Swift面向协议编程(视频,成绩单),Swift提供了许多功能,这些功能在许多情况下都使结构比类更好。 如果结构相对较小且可复制,则结构是可取的,因为与在类中多次引用同一实例相比,复制要安全得多。 当将变量传递给许多类和/或在多线程环境中时,这一点尤其重要。 如果您始终可以将变量的副本发送到其他位置,则不必担心其他位置会更改您下面的变量的值。 使用Structs,无需担心内存泄漏或多个线程争用访问/修改变量的单个实例的麻烦。 (从更专业的角度来说,例外是在闭包内部捕获结构时,因为它实际上是在捕获对实例的引用,除非您明确地将其标记为要复制)。 类也可能变得肿,因为一个类只能从单个超类继承。 这鼓励我们创建巨大的超类,其中包含仅松散相关的许多不同能力。 使用协议,尤其是使用协议扩展(可以在其中提供协议的实现),可以消除类对实现此类行为的需要。 演讲列出了首选班级的这些情况: 复制或比较实例没有意义(例如Window) 实例生存期与外部影响(例如TemporaryFile)相关实例只是“接收器”-到外部状态(例如CGContext)的只写管道 这意味着结构应该是默认值,而类应该是后备值。
  • Java是“按引用传递”还是“按值传递”?(Is Java “pass-by-reference” or “pass-by-value”?)
    问题 我一直认为Java使用传递引用。 但是,我已经看到一些博客文章(例如,该博客)声称不是(博客文章中说Java使用值传递)。 我不认为我能理解他们的区别。 有什么解释? 回答1 Java总是按值传递。 不幸的是,我们根本不处理任何对象,而是处理称为引用的对象句柄(当然是通过值传递) 。 选择的术语和语义很容易使许多初学者感到困惑。 它是这样的: public static void main(String[] args) { Dog aDog = new Dog("Max"); Dog oldDog = aDog; // we pass the object to foo foo(aDog); // aDog variable is still pointing to the "Max" dog when foo(...) returns aDog.getName().equals("Max"); // true aDog.getName().equals("Fifi"); // false aDog == oldDog; // true } public static void foo(Dog d) { d.getName().equals("Max"); // true // change d inside of foo() to point to a new Dog
  • 通过引用还是通过值? [关闭](Pass by reference or pass by value? [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 在学习新的编程语言时,您可能会遇到的障碍之一是该语言默认情况下是按值传递还是按引用传递。 所以这是我向大家提出的问题,用您最喜欢的语言,实际上是如何完成的? 可能的陷阱是什么? 您最喜欢的语言当然可以是您曾经玩过的任何东西:流行,晦涩,深奥,新颖,古老... 回答1 这是我对Java编程语言的贡献。 首先一些代码: public void swap(int x, int y) { int tmp = x; x = y; y = tmp; } 调用此方法将导致以下结果: int pi = 3; int everything = 42; swap(pi, everything); System.out.println("pi: " + pi); System.out.println("everything: " + everything); "Output: pi: 3 everything: 42" 即使使用“真实”对象也将显示类似的结果: public class MyObj { private String msg; private int
  • 分配后,JavaScript函数绑定(此关键字)丢失(JavaScript function binding (this keyword) is lost after assignment)
    问题 这是JavaScript中最神秘的功能之一,将对象方法分配给其他变量后,绑定(此关键字)丢失了 var john = { name: 'John', greet: function(person) { alert("Hi " + person + ", my name is " + this.name); } }; john.greet("Mark"); // Hi Mark, my name is John var fx = john.greet; fx("Mark"); // Hi Mark, my name is 我的问题是: 1)作业后发生了什么? var fx = john.greet; 是按值复制还是按引用复制? fx和john.greet指向两个不同的函数,对吗? 2)由于fx是全局方法,因此作用域链仅包含全局对象。 变量对象中此属性的值是什么? 回答1 1) fx和john.greet指的是同一个函数对象,对象的赋值操作通过reference进行。 对于原始值,例如String , Number , Boolean undefined或null ,将创建该值的副本。 2) this值引用全局对象。 this值不是变量对象的属性,它与作用域链无关,是一个特殊的保留字,并且在调用函数时隐式确定(您也可以通过call或apply显式设置它) 。