字符串不是对象,那么为什么它们有属性

Strings are not object then why do they have properties?

本文关键字:为什么 属性 对象 字符串      更新时间:2023-09-26

如下代码:

var str = "Hello StackOverflow !";
alert(typeof str);

给出string作为结果。这意味着字符串不是对象,那么为什么我们有字符串str的属性,如str.substring, str.indexOf etc.? 当我将属性设置为

str.property = "custom property is set";并试图得到这个alert(str.property),它给了我undefined。为什么?

像"Hello"这样的字符串在JavaScript中不是对象,但是当用于像

这样的表达式时
"Hello".indexOf(2)

生成一个从构造函数String派生的新对象,将字符串"Hello"包裹起来。indexOfString.prototype的属性,所以事情会像预期的那样工作,即使有很多魔法在发生。

在以下情况下

> var s = "xyz"; s.prop = 1; console.log(s.prop);
undefined

你看到undefined的原因是:

  1. 给变量s一个值,该值是一个原始字符串
  2. s.prop = 1和属性名为prop被分配给一个新的,匿名包装器对象。
  3. 在上面的第三个语句中,创建了另一个新对象来包装原语s。这与第二个语句中的包装器对象不同,并且它没有prop属性,因此在根据基本JavaScript规则请求其值时产生undefined

string是对象吗?

这取决于您如何定义对象以及当您说字符串时所指的是什么。当您使用单词string时,您可以只引用原语或包装器对象。

什么是原语?

在JavaScript中有5种基本类型:undefined, null, boolean, string和number。其他的都是对象。

与对象不同,原语没有真正的属性。它们以价值的形式存在。这解释了为什么不能将属性赋值给字符串:

var archy = "hello";
archy.say = "hello";
console.log(archy.say); // undefined

但是有时操作一个原语会让人觉得她/他在操作一个对象,因为原语似乎有方法。

var archy = "hello";
console.log(archy.length); //5

这是因为当你试图访问一个原语的任何属性时,JavaScript会创建一个包装器对象。

什么是包装器对象?

Javascript: The Definitive Guide

访问字符串的属性时创建的临时对象,数字或布尔值被称为包装器对象,它可以有时需要区分字符串值和字符串对象或来自数字或布尔对象的数字或布尔值。但是,包装器对象通常可以被视为一种实现细节,你不需要考虑它们。你只需要知道该字符串、数字和布尔值与对象的不同之处在于它们的属性是只读的,不能定义new

字符串是纯对象:http://www.ecma-international.org/ecma-262/5.1/#sec-15.5

问题是,typeof运算符。它只是根据其ECMA规范进行操作:

http://www.ecma-international.org/ecma-262/5.1/sec-11.4.3

字符串实际上是一种特殊的对象。您不能给它们添加属性,但是您可以修改String.prototype,它是任何string变量的原型,并为其添加属性,如下所示:

String.prototype.foo = 1;
var a = 'hello';
console.log(a.foo); // logs 1

JavaScript是一种原型基础语言,您可以为变量定义属性。字符串也有预定义的属性和方法可以使用。

更多信息