为什么我不能在javascript中为字符串对象添加属性?

时间:2011-03-05 02:05:39

标签: javascript

我继承了另一个开发人员写的一些javascript代码。他不喜欢我们在整个项目中使用的网格组件,因此他决定编写自己的网格组件。他写的网格无法对日期进行排序,因为它只能绑定到字符串/数字。在使用之前,他将所有日期转换为字符串。我查看了他编写的日期函​​数的字符串格式,并认为我可以只使用原始值为字符串添加日期属性,然后在排序时查看字符串是否具有日期属性并基于此排序。但是,似乎您无法在javascript中向字符串添加属性。我不知道有些类型你不能添加属性。例如:

<html>
<script>
var test = "test";
test.test = "test inner";
console.log(test);
console.log(test.test);
</script>

test.test将是未定义的。奇怪的。我的问题是为什么这段代码不起作用?而且,如果你能想到在该网格上排序日期的任何变通方法(除了实际绑定到日期对象而不是字符串,这将很难修复),这将非常有用。

2 个答案:

答案 0 :(得分:79)

JavaScript中有6种语言类型:

  • 5种原始类型: String Number Boolean Null Undefined
  • 1个非原始类型: Object

基元类型的值称为基元值,它们不具有属性 Object 非基本类型的值称为对象,它们可以具有属性。

当您尝试将名为'bar'的属性分配给变量foo时,如下所示:

foo.bar = 'abc';

然后结果将取决于foo的值的类型:

(a)如果foo的值属于 Undefined Null ,则会引发错误,

(b)如果foo的值属于 Object 类型,则会在对象上定义命名属性'bar' foo(如有必要),其值将设置为'abc'

(c)如果foo的值属于 Number String Boolean ,那么变量foo将不会以任何方式改变。在这种情况下,上述赋值操作将是noop

因此,正如您所看到的,只有那些变量是对象,才能将属性赋值给变量。如果不是这种情况,则分配将完全不执行任何操作,甚至抛出错误。


在您的情况下,变量test包含 String 类型的值,因此:

test.test = "test inner";

什么都不做。


然而,由于ES5引入了访问器属性,我上面说的有一个例外。访问器属性允许我们定义在检索或设置属性时调用的函数。

例如:

var str = '';
str.prop;

此处str是一个包含 String 值的变量。因此,访问该变量的属性应该是no-op(str.prop仅返回undefined)。这是一个例外:如果String.prototype包含具有已定义的getter的访问者属性'prop',则将调用该getter。

所以,如果定义了这个:

Object.defineProperty( String.prototype, 'prop', {
    get: function () {
        // this function is the getter
    }
}); 

然后这个

str.prop;

将调用该getter函数。

现场演示: http://jsfiddle.net/fmNgu/

但是,我不认为向内置原型添加访问器属性是一种很好的做法。

答案 1 :(得分:28)

如果使用String对象,则可以添加属性:

var test = new String("test");
test.test = "test inner";
console.log(test.toString()); // prints out "test"
console.log(test.test); // prints out "test inner"