第一次翻译,能够有许多处所不适当,迎接斧正。
原文地点:http://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/
你能够不晓得,在javascript中,在运用string, number, 布尔范例这些原始值时,都邑碰到意想不到的题目。浏览下文,来发表内里的隐秘。
基本引见
对象就是各个属性的鸠合,属性可所以对一个对象的援用或是一个原始值,原始值是一个值,他们没有属性。
在 JS 里的五类原始范例是:undefined, null, boolean, string 和 number."其他"的范例都是对象.个中 boolean, string 和 number 原始范例能够被对应的对象范例包裹.这些对象都应该是 Boolean, String 和 Number 类的实例。
typeof true; //"boolean"
typeof Boolean(true); //"boolean"
typeof new Boolean(true); //"object"
typeof (new Boolean(true)).valueOf(); //"boolean"
typeof "abc"; //"string"
typeof String("abc"); //"string"
typeof new String("abc"); //"object"
typeof (new String("abc")).valueOf(); //"string"
typeof 123; //"number"
typeof Number(123); //"number"
typeof new Number(123); //"object"
typeof (new Number(123)).valueOf(); //"number"
假如原始值没有属性,那为何”abc”.length能返回值?
由于javascript在原始值与对象之间很轻松的交换范例。在这类情况下,为了获得length属性,字符串的value值就被强迫转换为字符串对象。String对象仅仅是被霎时转换,然后会被当着渣滓接纳处置惩罚掉。关于这类征象,我们先避开这个难明的谜团,接下来逐步剖析它。
String.prototype.returnMe= function() {
return this;
}
var a = "abc";
var b = a.returnMe();
a; //"abc"
typeof a; //"string" (still a primitive)
b; //"abc"
typeof b; //"object"
然则你会发明,只需这个对象还存在,这个对象不会被当着渣滓接纳来处置惩罚。
在strict形式下,这类征象不会涌现。
这里有一个典范的实例来诠释这个对象没有被当着渣滓接纳来处置惩罚掉。
Number.prototype.toString = function() {
return typeof this;
}
(123).toString(); //"object"
也就是说原始值是有属性的(包括要领),这些属性是他们各自的原型所定义的。
这些对象能被强迫转换为values吗?
是的,大多数情况下,对象仅仅是容器,value是他们包括的原始值,他们会按需的强迫性转换为对应的value值。来看下面的实例:
//object coerced to primitive
var Twelve = new Number(12);
var fifteen = Twelve + 3;
fifteen; //15
typeof fifteen; //"number" (primitive)
typeof Twelve; //"object"; (still object)
//another object coerced to primitive
new String("hippo") + "potamus"; //"hippopotamus"
//object not coerced (because 'typeof' operator can work with objects)
typeof new String("hippo") + "potamus"; //"objectpotamus"
奇怪的是boolean 对象不会被随意马虎的转换,除了碰到null 与undefined, boolean 对象都邑自动修正为true,尝尝这个:
if (new Boolean(false)) {
alert("true???");
}
一般你能够想清晰的晓得boolean 对象的value值,下面的做法能明白的判断value值是true,照样false
var a = "";
new Boolean(a).valueOf(); //false
然则,如许做能够更轻易些:
var a = Boolean("");
a; //false
以至是如许:
var a = "";
!!a; //false
强迫转换许可我们对一个原始值赋值吗?
答案是no
var primitive = "september";
primitive.vowels = 3;
primitive.vowels; //undefined;
假如javascript探测到试图对一个原始值赋值,事实上它会强迫把这个原始值转换为对象,然则,正如上面的实例,这个新对象是没有指针的,会马上被接纳处置惩罚掉。
这里有个伪代码实例来诠释这类征象:
var primitive = "september";
primitive.vowels = 3;
//new object created to set property
(new String("september")).vowels = 3;
primitive.vowels;
//another new object created to retrieve property
(new String("september")).vowels; //undefined
正如你看到的,这类写法不仅无效,而且是相称的糟蹋。
结论
末了证实相关于对原始值赋值,给对象赋值是它的一个唯一上风。然则在实践中,这类做法也是可疑的。Strings, booleans 与numbers有着特定的,定义好的用处。从新定义他们恰好让人难以明白。而且,原始值是不可变的,你不能够经由过程转变他们的属性值来修正他们。
var me = new String("Angus");
me.length = 2; //(error in strict mode)
me.length; //5 (not 2 - thanks @joseanpg)
me.valueOf(); "Angus"
而且,我以为对原始值深切的明白,以及当运用他们的时刻晓得详细发生了什么是深切明白这门言语迈出主要的一步。