为什么我不能在 javascript 中向字符串对象添加属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5201138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't I add properties to a string object in javascript?
提问by Shawn
I inherited some javascript code another developer wrote. He didn't like the grid component we used throughout the project, so he decided to write his own. The grid he wrote can't sort dates, because it can only bind to strings / numbers. He converts all dates to strings before using them. I looked at the string formatting of date function he wrote, and figured I could just add a date property to the string with the original value, and then when sorting see if the string has a date property and sort based on that. However, it seems like you can't add properties to strings in javascript. I wasn't aware there were certain types you can't add properties to. For example:
我继承了另一个开发人员编写的一些 javascript 代码。他不喜欢我们在整个项目中使用的网格组件,所以他决定自己编写。他写的网格不能对日期进行排序,因为它只能绑定到字符串/数字。在使用它们之前,他将所有日期转换为字符串。我查看了他编写的日期函数的字符串格式,并认为我可以将日期属性添加到具有原始值的字符串中,然后在排序时查看字符串是否具有日期属性并基于该属性进行排序。但是,您似乎无法在 javascript 中向字符串添加属性。我不知道您无法向某些类型添加属性。例如:
<html>
<script>
var test = "test";
test.test = "test inner";
console.log(test);
console.log(test.test);
</script>
test.test will be undefined. Weird. My question is why this code doesn't work? And also, if you can think of any workarounds for sorting dates on that grid (besides actually binding to date objects instead of strings, which would be a pain to fix,) that would be really helpful.
test.test 将是未定义的。奇怪的。我的问题是为什么这段代码不起作用?而且,如果您能想到在该网格上对日期进行排序的任何变通方法(除了实际绑定到日期对象而不是字符串,这将很难修复),那将非常有帮助。
回答by ?ime Vidas
There are 6 language types in JavaScript:
JavaScript 中有 6 种语言类型:
- 5 primitive types: String, Number, Boolean, Null, Undefined
- 1 non-primitive type: Object
- 5 种基本类型:String、Number、Boolean、Null、Undefined
- 1 非原始类型:对象
Values of the primitive types are called primitive values and they cannot have properties.
Values of the Objectnon-primitive type are called objects an they can have properties.
原始类型的值称为原始值,它们不能具有属性。
所述的值对象非原始型被称为对象的它们可具有的特性。
When you try to assign a property named 'bar'
to a variable foo
, like so:
当您尝试将命名的属性分配给'bar'
变量时foo
,如下所示:
foo.bar = 'abc';
then the result will depend on the type of the value of foo
:
那么结果将取决于 的值的类型foo
:
(a)if the value of foo
is of the type Undefinedor Null, then an error will be thrown,
(a)如果 的值为Undefined或Nullfoo
类型,则会抛出错误,
(b)if the value of foo
is of the type Object, then a named property 'bar'
will be defined on the object foo
(if necessary), and its value will be set to 'abc'
,
(b)如果 的值为Objectfoo
类型,则将在对象上定义命名属性(如有必要),并将其值设置为, 'bar'
foo
'abc'
(c)if the value of foo
is of the type Number, Stringor Boolean, then the variable foo
will not be changed in any way. In this case, the above assignment operation will be a noop.
(c)如果 的值为Number、String或Booleanfoo
类型,则变量不会以任何方式改变。在这种情况下,上述赋值操作将是一个noop。foo
So, as you can see, assigning properties to variables only makes sense if those variables are objects. If that is not the case, then the assignment will either do nothing at all, or even throw an error.
因此,如您所见,只有当这些变量是对象时,才能为变量分配属性。如果不是这种情况,那么赋值要么什么也不做,要么抛出一个错误。
In your case, the variable test
contains a value of the type String, so this:
在您的情况下,该变量test
包含String类型的值,因此:
test.test = "test inner";
does nothing at all.
什么都不做。
However, since ES5 introduced accessor properties, there is an exception to what I've said above. Accessor properties allow us to define functions which are invoked whenever the property is either retrieved or set.
然而,由于 ES5 引入了访问器属性,所以我上面所说的有一个例外。访问器属性允许我们定义在检索或设置属性时调用的函数。
For instance:
例如:
var str = '';
str.prop;
Here str
is a variable holding a Stringvalue. Therefore, accessing a property of that variable should be a no-op (str.prop
merely returns undefined
). This is true with one exception: if String.prototype
contains a accessor property 'prop'
with a defined getter, then that getter will be invoked.
这str
是一个保存字符串值的变量。因此,访问该变量的属性应该是空操作(str.prop
仅返回undefined
)。这是真的,但有一个例外:如果String.prototype
包含'prop'
具有已定义 getter的访问器属性,则将调用该 getter。
So, if this is defined:
所以,如果这是定义:
Object.defineProperty( String.prototype, 'prop', {
get: function () {
// this function is the getter
}
});
then this
那么这个
str.prop;
will invoke that getter function.
将调用该 getter 函数。
Live demo:http://jsfiddle.net/fmNgu/
现场演示:http : //jsfiddle.net/fmNgu/
However, I don't think that adding accessor properties to the built-in prototypes would be a good practice.
但是,我不认为向内置原型添加访问器属性是一个好习惯。
回答by treaint
If you use a String object you can add properties:
如果使用 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"