Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么不是';JavaScript中的所有内容都是可分配的吗?_Javascript - Fatal编程技术网

为什么不是';JavaScript中的所有内容都是可分配的吗?

为什么不是';JavaScript中的所有内容都是可分配的吗?,javascript,Javascript,我是在“JavaScript面向对象和可分配的一切”范式中长大的。所以我过着幸福的生活,直到 var x = {}; x.field = true; x.field.netType = "System.Boolean"; alert(x.field.netType); 它会编译,但警报会一直显示met“未定义”。为什么 x.field = true; x.field.netType = "System.Boolean"; 实际上正在工作。 x.field是一个基本的布尔值,它在内部被

我是在“JavaScript面向对象和可分配的一切”范式中长大的。所以我过着幸福的生活,直到

var x = {};

x.field = true;
x.field.netType = "System.Boolean";

alert(x.field.netType);
它会编译,但警报会一直显示met“未定义”。为什么

x.field = true; 
x.field.netType = "System.Boolean"; 
实际上正在工作。
x.field
是一个基本的布尔值,它在内部被转换为object,但我们没有它的引用,所以它会立即变成垃圾。如果我们存储
x.field
的引用,这样它就不会是垃圾,我们就可以得到值。像这样

x.field = true;  
var y = x.field.netType = "System.Boolean"; 
alert(y); 
如果你这样写代码

var x = {};

x.field = {};
x.field.netType = "System.Boolean";

alert(x.field.netType);
那就行了

在代码中,这一行
x.field.netType=“System.Boolean”将在“严格”模式下引发错误

`//Cannot assign to read only property 'netType' of true`
为什么此行
x.field.netType
给出了
未定义的

这种类型的对象只是包装器,它们的值是它们包装的原语,它们通常会根据需要强制降低到这个值

JavaScript将很容易在
原语和对象之间进行强制

var a = 'Intekhab';
 a.length;//In this case the string value is coerced to a string object in order to access the property length.

var Twelve = new Number(12); 
var fifteen = Twelve + 3; // In this case Object Twelve is coerced to a primitive value.
fifteen; //15
如果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
JavaScript中的原语(字符串、数字、
true
false
)是而不是对象。但是,当它们与
[]
一起使用时,就像它们是对象一样,语言通过隐式地为它们构造对象包装器来满足需要

在你的例子中,就是这样。对object属性的赋值确实有效,因此没有错误,但包装器对象随即被丢弃

另一方面:

var x = {};

x.field = new Boolean(true);
x.field.netType = "System.Boolean";

alert(x.field.netType);

(我不建议实际这样做;使用由原始包装器类型生成的对象往往会产生奇怪的效果,因为这些值会传播到不需要它们的代码中。)

x.field
是一个布尔值;布尔值是基本值,是只读的。当您尝试为
x.field.netType
赋值时,您正在尝试修改
x.field
的值。波蒂的回答主要解释了这一点

当处于“正常”JavaScript模式时,这将导致值仅为未定义的

原因为什么评论中有人建议使用严格模式(您肯定应该使用)严格模式将抛出一个错误,通知您正在尝试将值分配给只读值,并阻止您这样做,而不是在您访问该属性时以静默方式返回
undefined

'use strict';
var foo = true;
foo.bar = 'qux'; // this line will throw an Error
根据Pointy的例子,它实际上确实发生了错误,至少在节点4.0上是这样。我不知道JS engine Pointy在使用什么,但它运行不正常

> (function() { 'use strict'; (true).x = 0; })()
TypeError: Cannot assign to read only property 'x' of true
    at repl:1:38
    at repl:1:45
    at REPLServer.defaultEval (repl.js:154:27)
    at bound (domain.js:254:14)
    at REPLServer.runBound [as eval] (domain.js:267:12)
    at REPLServer.<anonymous> (repl.js:308:12)
    at emitOne (events.js:77:13)
    at REPLServer.emit (events.js:169:7)
    at REPLServer.Interface._onLine (readline.js:209:10)
    at REPLServer.Interface._line (readline.js:548:8)
>(函数(){'use strict';(true).x=0;})()
TypeError:无法分配给true的只读属性“x”
回复:1:38
回复:1:45
在REPLServer.defaultEval(repl.js:154:27)
绑定时(domain.js:254:14)
在REPLServer.runBound[as eval](domain.js:267:12)
在服务器上。(回复js:308:12)
在emitOne(events.js:77:13)
在REPLServer.emit上(events.js:169:7)
在REPLServer.Interface.\u在线(readline.js:209:10)
在REPLServer.Interface.\u行(readline.js:548:8)

这只是答案的一半……它解释了为什么您得到了未定义的
。但这并不能解释为什么这项任务一开始似乎有效。除此之外,问题不是如何解决这个问题,而是原因是什么,@Pointy的答案要好得多。这不够清楚,在某种程度上是“错误的”,因为执行var t=new Boolean();t、 foo=“bar”;它实际上在工作。它可能误导OP.@Pointy答案更准确。你有任何文档支持你的答案吗?加入
“使用严格”在顶部,并查看魔术;-)@第四个?“严格模式会在这里做什么?”尖刻的抱怨道。它会抱怨。严格模式是那个不让你做最吸引人的事情的挑剔女孩,而非严格模式是一个反面教材。@IsmaelMiguel hmm
(function(){“use Strict”;(true).x=0;})(
-我没有抱怨。@Bergi:已经看过了,没有找到任何好的答案。顺便说一句,规范中提到了严格模式“LeftHandSide也可能不是对属性值为{[[Writable]]:false}的数据属性的引用,对属性值为{[[Set]]:undefined}的访问器属性的引用,也可能不是对[[Extensible]]的对象的不存在属性的引用内部插槽的值为false。在这种情况下,会引发TypeError异常(12.14)。“但是,它看起来不像是
[[Extensible]]:当以这种方式强制原语时,会设置false
,所以是的,看起来V8是错误的?有关于这种行为的文档吗?@KeesC.Bakker有一些错误,但这不容易阅读。我可以想象,任何好的JavaScript引用都必须涉及到这种行为,因为它是语言的基础。像检查字符串长度这样常见的事情会导致隐式对象包装。@KeesC.Bakker:您可能会感兴趣:。在规范中,拳击是在这里定义的:(但是没有上下文就没有真正的价值,即知道如何/在哪里调用
GetValue
)。警告:
new Boolean(false)
是一个真实的值。@Keen是的,确切地说,
typeof new String(“hello”)
“object”
,因为我不能对主要答案发表评论,你关于严格模式的例子和问题在这里。@mikeTheLiar你的名字很适合你!JavaScript确实是一种JIT编译语言,自从IE9.Noje.js使用V8引擎(与Chrome相同),而我们(me和Pointy)使用Firefox以来,JavaScript就一直在使用。在Firefox中,它不会出错。但在V8引擎上确实如此。应该注意的是,这种行为似乎违反了规范。