资讯专栏INFORMATION COLUMN

翻译:Javascript原始值解析

yeyan1996 / 894人阅读

摘要:结论最后证明相对于对原始值赋值,给对象赋值是它的一个唯一优势。而且,原始值是不可变的,你不可能通过改变他们的属性值来修改他们。而且,我认为对原始值深刻的理解,以及当使用他们的时候知道具体发生了什么是深入理解这门语言迈出重要的一步。

第一次翻译,可能有很多地方不恰当,欢迎指正。

原文地址: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"

而且,我认为对原始值深刻的理解,以及当使用他们的时候知道具体发生了什么是深入理解这门语言迈出重要的一步。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85272.html

相关文章

  • JavaScript中,{}+{} 等于多少?

    摘要:如果返回值是一个原始值,则返回这个原始值。如果或者中的任意一个为字符串,则将另外一个也转换成字符串,然后返回两个字符串连接操作后的结果。因此,的结果实际上是两个空字符串的连接。 原文:What is {} + {} in JavaScript? 译者:justjavac 最近,Gary Bernhardt 在一个简短的演讲视频Wat中指出了一个有趣的 JavaScript 怪癖...

    Jrain 评论0 收藏0
  • 前端资源系列(5)-JavaScript奇味探索

    摘要:中有很多奇妙的东西,归咎归功于设计时候的迅速。缺陷有,但是的强大确实体现的淋漓尽致。它是如此的灵活,当然随之而来的便是开发的代价,它不像强类型语言那样规规矩矩。难得周末晚上清闲,回味这些看起来有点怪怪却又在发生着的问题。 JavaScript中有很多奇妙的东西,归咎or归功于设计时候的迅速。缺陷有,但是JavaScript的强大确实体现的淋漓尽致。 它是如此的灵活,当然随之而来的便是开...

    kyanag 评论0 收藏0
  • eval()不是魔鬼,只是被误解了(翻译

    摘要:因为道格拉斯的大多数作品并没有注明日期,所以,我不确定他是否是在年创造了这个术语。但这并不能说明是魔鬼,这只是开发工作流程中的一点问题。中间人攻击被认为是的永远存在的危险,会受到蠕虫的的攻击。 原文来自:https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/ 作者:Nicholas C.Z...

    elarity 评论0 收藏0
  • JavaScript Puzzlers! 解惑(一):为什么 ["1", &qu

    摘要:第一题为的返回值。返回值其中的每个元素均为关联的原始数组元素的回调函数返回值的新数组。修改数组对象数组对象可由回调函数修改。方法启动后的条件元素是否传递给回调函数在数组的原始长度之外添加元素。 JavaScript Puzzlers! 被称为 javascript 界的专业八级测验,感兴趣的 jser 可以去试试。 我试了一下, 36 道题只做对了 19 道, 算下来正确率为 53%,...

    k00baa 评论0 收藏0
  • JavaScript机器学习之线性回归

    摘要:不能用于机器学习太慢幻觉矩阵操作太难有函数库啊,比如只能用于前端开发开发者笑了机器学习库都是开发者机器学习库神经网络神经网络自然语言处理卷积神经网络一系列库神经网络深度学习我们将使用来实现线性回归,源代码在仓库。 译者按: AI时代,不会机器学习的JavaScript开发者不是好的前端工程师。 原文: Machine Learning with JavaScript : Part 1 ...

    gitmilk 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<