一切都是物体
Everything is an object?
在一个流行的博客上,作者问他的听众他们对JavaScript的"啊哈!"时刻是什么,大多数人说它意识到JavaScript中的所有内容都是一个对象。但是作为JS和编程的新手,我不太明白这意味着什么。它不像与实际的JS对象相关 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
还是有?
如果没有,请解释一下"JavaScript 中的所有内容都是对象"是什么意思。
或者它都是关于OO编程的,阅读有关此主题的内容将有助于理解它?你能推荐一下关于这个主题的阅读内容吗?
它们的意思很可能是,任何可以分配给变量的数据都具有可以通过类似对象的方式访问的属性(因此也是方法(。
// strings
"asdf".length; // 4
"asdf".replace('f', 'zxc'); // "azxc"
// numbers
(10).toFixed(2); // "10.00"
// booleans
true.someProp; // undefined (point is it doesn't crash)
他们甚至有继承的原型。
"omg".constructor; // function String() { [native code] }
String.prototype.snazzify = function() {
return "*!*!*" + this + "*!*!*";
};
"omg".snazzify(); // "*!*!*omg*!*!*"
但是,这些是原语,虽然它们在很多方面都像对象一样,但它们在某些方面与其他"真正的"JS对象不同。 其中最大的一点是它们是不可变的。
var s = "qwerty";
s.foo; // undefined, but does not crash
s.foo = 'some val'; // try to add a property to the string
s.foo; // still undefined, you cannot modify a primitive
请注意,函数是真正的可变对象。
var fn = function(){};
fn.foo; // undefined
fn.foo = 'some val'; // try to add a property to the function
fn.foo; // "some val"
因此,虽然"JS中的所有内容都是对象"在技术上是不正确的,但在大多数情况下,您可以将它们视为对象,因为它们具有属性和方法,并且可以扩展。 只要确保您了解注意事项即可。
回到第一原则。
什么是对象? 它是一个软件组件,将状态和行为封装到内存中的单个实体中。
根据这个定义,你可以看到所有东西都可以被认为是一个对象。 函数式程序员使函数成为第一类对象。 数据人员会说,即使没有行为的数据,也可以被认为是一个对象(尽管不是一个非常聪明的对象(。
我看不出这有什么变化。
JavaScript 将函数视为对象。
我不确定这种见解会对您的编程产生什么影响。
在 JavaScript 中,并非所有内容都是对象。例如,数字不是对象。
不同的语言对"对象"有不同的定义。对于 JavaScript,官方定义可以在 ECMAScript 语言规范中找到,其中指出:
在 ECMAScript 中,对象是零个或多个属性的集合每个属性都具有确定如何使用每个属性的属性 (...(属性是保存其他对象的容器,基元值或函数。基元值是基元值的成员以下内置类型:未定义、空值、布尔值、数字、BigInt、字符串和符号;对象是内置类型的成员对象;函数是可调用的对象。
因此,根据这个定义,很明显原始值(如数字(不是对象。甚至字符串也不是对象,这与大多数其他OO语言不同。
那么为什么有人说"一切都是物体"呢?你必须问他们!但我怀疑这是因为它们被内置对象Number
、Boolean
、String
等混淆了,这些对象可以用作相应原始值的包装器。这种包装有时会自动发生,这会使基元值看起来像对象,例如允许您(看似(访问基元的属性。但实际上,属性位于包装器对象上。
并非 JavaScript 中的所有内容都是对象。
JavaScript 中的所有数据都必须属于六种基元类型或对象类型之一。基元类型包括布尔型、null
型、undefined
型、字符串、数字和符号;所有不是基元的东西都是对象。
数组是对象,ES6 类将脱糖分解为函数,函数是对象。
出现混淆是因为基元值具有对象包装器。当您尝试访问字符串文本上的 length
属性时,JavaScript 会在基元周围创建一个临时对象包装器,并访问该对象包装器的 length 属性。检索属性后,将丢弃对象包装器。这称为自动装箱。
本质上,它的实现类似于以下内容:
const foo = "bar";
// When you run `foo.length`, it's similar to
tmp = String(foo);
tmp.length;
delete tmp;
或
const foo = "bar";
(new String(foo)).length;
字符串、数字和布尔基元具有对象包装器,但null
和undefined
没有。因此,尝试从这些基元访问属性或方法会引发错误。
null.length; // Uncaught TypeError: Cannot read property 'length' of null
undefined.length; // Uncaught TypeError: Cannot read property 'length' of undefined
'几乎所有东西都是对象',因为主代码单元是JS对象。例如,在基元上,您不能像在所有对象上那样添加成员。我的答案为什么JS函数在这里是JS对象:https://stackoverflow.com/a/24811539
- 没有找到相关文章