【问题标题】:How is almost everything in Javascript an object?Javascript 中的几乎所有东西都是一个对象?
【发布时间】:2012-02-02 08:05:30
【问题描述】:

我在很多 JavaScript 介绍中都读到了这个。我只是不明白。我一直认为对象是具有方法和属性的东西。 我理解的数组,因为它具有键值对。 “字符串”或“数字”或“函数”怎么样? 上面列出的这些东西对我来说似乎是功能。这意味着你输入一些东西,你得到一些东西。您并没有真正获得访问属性或任何东西。数组或这个“对象”列表中没有使用点表示法。

有没有人用点符号来编写每个例子的代码来访问它的方法和属性?我怀疑对象的定义可能是有限的,因为我确实开始学习 JavaScript...

【问题讨论】:

  • 您是否学习过经典的面向对象(您可以构建类并从中创建大量实例的那种,例如 C++ 或 Java)语言?这可能有助于回答问题。

标签: javascript oop


【解决方案1】:

不,不是所有的东西都是 JavaScript 中的对象。您经常与之交互的许多事物(字符串、数字、布尔值)都是原语,而不是对象。与对象不同,原始值是不可变的。由于这些原语确实具有对象包装器(StringNumberBoolean),情况变得复杂;这些对象具有方法和属性,而基元没有,但基元似乎具有方法,因为当代码尝试访问基元的任何属性时,JavaScript 会默默地创建一个包装对象。

例如,考虑以下代码:

var s = "foo";
var sub = s.substring(1, 2); // sub is now the string "o"

在幕后,s.substring(1, 2) 的行为就好像它正在执行以下(近似)步骤:

  1. s创建一个包装器String对象,相当于使用new String(s)
  2. 在步骤 1 返回的 String 对象上使用适当的参数调用 substring() 方法
  3. 处置String 对象
  4. 从第 2 步返回字符串(原始)。

这样做的结果是,虽然看起来您可以将属性分配给基元,但这是没有意义的,因为您无法检索它们:

var s = "foo";
s.bar = "cheese";
alert(s.bar); // undefined

发生这种情况是因为该属性是在立即丢弃的String 对象上有效定义的。

数字和布尔值也是如此。然而,函数是成熟的对象,并且继承自 Object(实际上是 Object.prototype,但这是另一个主题)。因此,函数可以做任何对象可以做的事情,包括拥有属性:

function foo() {}
foo.bar = "tea";
alert(foo.bar); // tea

【讨论】:

  • 这个答案应该是最重要的:虽然选择的答案对于实际目的来说已经足够好了,但这个答案更彻底(也很有趣!)谢谢!
  • 这是正确的答案。并非一切都是对象。几乎所有东西都是一个对象。有关 javascript 中的类型,请参阅 developer.mozilla.org/en-US/docs/JavaScript/…
  • 好答案。不过有趣的是,如果您使用var s = new String('foo');,那么s.bar 将保留cheese 的值。
  • @SteveFenton:是的,因为new String('foo') 产生了一个String 对象,它的行为与任何其他对象一样,因为它继承自Object.prototype
  • 很好的解释!实际上,除了原始类型之外,一切都是对象。
【解决方案2】:

没错:在 JavaScript 中,几乎所有东西都是对象。但这些对象与我们在 Java、C++ 或其他传统语言中看到的有些不同。 JS 中的对象只是一个带有键值对的 hashmap。键始终是字符串或符号,值可以是任何东西,包括字符串、整数、布尔值、函数、其他对象等。所以我可以像这样创建一个新对象:

var obj = {}; // This is not the only way to create an object in JS

并向其中添加新的键值对:

obj['message'] = 'Hello'; // You can always attach new properties to an object externally

obj.message = 'Hello';

同样,如果我想给这个对象添加一个新函数:

obj['showMessage'] = function(){
  alert(this['message']);
}

obj.showMessage = function() {
  alert(this.message);
}

现在,每当我调用此函数时,它都会显示一个带有消息的弹出窗口:

obj.showMessage();

数组就是那些能够包含值列表的对象:

var arr = [32, 33, 34, 35]; // One way of creating arrays in JS

虽然您始终可以使用任何对象来存储值,但数组允许您存储它们而无需为每个对象关联一个键。所以你可以使用它的索引来访问一个项目:

alert(arr[1]); // This would show 33

数组对象,就像 JS 中的任何其他对象一样,都有它的属性,例如:

alert(arr.length); // This would show 4

如需深入了解,我强烈推荐 John Resig 的 Pro JavaScript Techniques

【讨论】:

  • 只是一个附录,与本主题无关,length 属性不返回数组中元素的数量。它返回该数组的lastIndex + 1。例如,在var x = []; x[100] = 5; alert(x.length) 中会提醒101
  • 不,不是 JavaScript 中的一切都是对象。字符串、数字、布尔值不是,尽管它们有对应的对象。
  • 因为“没错,在 javascript 中,一切都是一个对象。”...
  • “虽然你总是可以使用任何对象来存储值,但是数组允许你存储它们而不用为每个对象关联一个键。”根据规范,这是不正确的。 JS 中没有数组,只有 ARRAY OBJECTS。它们的工作方式是自动为每个属性赋予属性名称,该名称是数组中元素的索引。这是规范的 15.4。您可以使用括号表示法来获取 em,例如 myArray["0"] 将给出第一个对象
  • @DavidWiniecki 你是对的:这应该被否决,因为解释是错误的。虽然您可以访问"hello"[2] 或调用(4).toString(2),但这并不是因为这些原始值是对象,而是因为在读取属性之前它们被强制到对象。很快,我们可能会有三类 ECMAScript 值,这会更加混乱:原语、compound primitives 和对象。
【解决方案3】:

“在 JavaScript 中,几乎一切都是对象”这句话是正确的,因为 MAIN 代码单元(对象、函数、数组)是 JavaScript 对象。
JavaScript 代码使用 9 个不同的单位加 1 个(多个):
- 01. 数组
- 02. 布尔
- 03. 功能
- 04.null
- 05. 号码
- 06. 对象
- 07. 正则表达式
- 08. 字符串
- 09. 未定义
- 10. 多个

但是 JavaScript 对象:
- 与其他面向对象语言中的“对象”不同。
- 它们是名称-值-对的集合。
- 都有创造的功能(它的构造器)。
- 所有继承其构造函数的原型对象的成员,这是它的原型。
- 所有函数都是对象,但并非所有对象都是函数
- 函数有范围,对象没有(我认为这是一个设计缺陷)。
- 对象、函数、数组、字符串……第一个大写字母是函数!!!
- JS 对象和函数的差异比共同点更重要。
- JS 中的“instance”名称与知识论中的“instance”名称具有不同的含义,其中实例继承了其通用概念的属性。在 JS 中只表示它的构造函数。 JavaScript 从 'class-based-inheritance' ool (java) 中获得了名称 'instance',因为这些对象继承了类的属性,所以它是一个合适的名称。
JS 关键字“instanceof”的更好名称是“objectof”。

JS-functions ARE JS-objects 因为:
1) 他们可以拥有像 JS-objects 这样的成员:

> 函数 f(){} 不明确的 > f.s = "一个字符串" “一个字符串” > f.s “一个字符串”

2) 它们有一个构造函数,就像所有 JS 对象一样,Function 函数:

> (function f(){}) instanceof 函数 真的

3) 作为所有的 JS-objects,它们的prototype-object 与其构造函数原型相同:

> (function f(){}).__proto__ === Function.prototype 真的 > ({}).__proto__ === Object.prototype 真的 > (新对象).__proto__ === Object.prototype 真的

4) 当然,作为特定 JS 对象的 JS 函数具有和额外的属性,就像编程语言中的所有函数一样,JS 对象不具备这些属性,就像您可以使用输入和输出信息调用(执行)它们一样。

EVERYTHING 不是对象,因为例如,我们不能将成员添加到文字字符串:

> var s = "字符串" 不明确的 > s.s2 = "s2string" “s2string” > s.s2 不明确的

【讨论】:

  • 什么是倍数?我没有找到任何关于多类型谷歌搜索的参考。
  • 'multiple' 是一个可以|包含不同类型的单元,例如我们存储字符串、数字、数组的变量...
  • 代码和文本一样,是由更简单的实体到更复杂的实体组成的。在文本中,我们有字母、单词、名称、句子、段落……这些都是文本单元。以同样的方式我们有代码单元。
  • 这个答案引起的混乱比它清除的要多;到处都是。您所指的“代码单元”不是一个东西……
【解决方案4】:

在 javaScript 中,并不是所有的东西都是对象。 JavaScript 有原语和对象。 有六种原语——null、undefined、string、number、boolean 和 symbol。 由于可以访问的属性和功能,似乎所有东西都充当对象。例如-

var stringvar="this string";
typeof stringvar; // "string"
stringvar.length; //11

现在由于“stringvar”是一个字符串类型,它是一个原始类型,它不应该能够访问属性长度。它可以这样做是因为一个叫做 Boxing 的东西。Boxing 是任何原始类型转换为的过程一个对象类型,反之称为拆箱。这些对象类型或对象包装器是在创建时考虑到一些可能需要对原始值执行的常见操作。它们包含有用的方法和属性,并且是链接到原语。 就对象而言,键值对可以添加到每个对象,甚至是数组。

var arr=[1,2,3];
arr.name="my array";
arr;  //[1,2,3,name:'my array']

这并不意味着数组的第四个元素是“name:'my array'”。“name”是一个属性,可以用点表示法(arr.name)或括号表示法(arr[“name "])。

【讨论】:

  • 还有bigInt
【解决方案5】:

根据 developer.mozilla.org 和 ECMAScript 规范,答案是否定的。从技术上讲,并非一切都是对象。

https://developer.mozilla.org/en-US/docs/Glossary/Primitive

在 JavaScript 中,原始(原始值,原始数据类型)是不是对象且没有方法的数据。原始数据类型有 7 种:string、number、bigint、boolean、null、undefined、symbol

原语不是对象,没有方法,它也是不可变的。除了 null 和 undefined,所有其他原语都有一个包装对象,为您提供一些可以使用的功能。例如,String 表示字符串原语。

https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript

所以在下面的代码中,当你在原始数据 name 上调用 toUpperCase() 时,JavaScript 会自动包装字符串原始数据并调用 String 对象的 toUpperCase 函数

var name = 'Tom';
console.log(name);

name.toUpperCase();
console.log(name); 

在原始字符串上调用方法或发生属性查找的上下文中,JavaScript 将自动包装字符串原始并调用方法或执行属性查找。

还要注意 JavaScript 区分字符串对象和原始字符串值。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Distinction_between_string_primitives_and_String_objects

var nameP = 'Tom';
var nameO = new String(nameP);

typeof nameP // "string"
typeof nameO // "object"

【讨论】:

  • 感谢您的回答。提供文档中的信息作为参考很酷!
  • 所有的工厂函数都会产生“对象”,不管它们的名字是什么,所以即使是Function和String这样的构造函数也会产生对象。感谢您的回答。
猜你喜欢
  • 2012-02-24
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
相关资源
最近更新 更多