Javascript 什么&x2019;代码中的数字对象持有属性并递增数字时会发生什么情况?
包含此JavaScript片段Javascript 什么&x2019;代码中的数字对象持有属性并递增数字时会发生什么情况?,javascript,Javascript,包含此JavaScript片段 > function dis() { return this } undefined 有人能一步一步地解释一下里面发生了什么吗 > function dis() { return this } undefined > five = dis.call(5) Number {[[PrimitiveValue]]: 5} > five.wtf = 'potato' "potato" > five.wtf "potato" > fiv
> function dis() { return this }
undefined
有人能一步一步地解释一下里面发生了什么吗
> function dis() { return this }
undefined
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
> five.wtf = 'potato'
"potato"
> five.wtf
"potato"
> five * 5
25
> five.wtf
"potato"
> five++
5
> five.wtf
undefined
> five.wtf = 'potato?'
"potato?"
> five.wtf
undefined
> five
6
特别是,我不清楚:
- 为什么
的结果是一个带有某种dis.call(5)
属性的[[PrimitiveValue]]
,但是Number
和five++
的结果似乎只是普通的数字five*5
和5
(不是25
s)Number
- 为什么
属性在five.wtf
增量后消失five++
- 为什么
属性在five.wtf
增量之后甚至不再可设置,尽管five++
赋值显然设置了值five.wtf='potato?'
这很简单
function dis () { return this; }
这将返回This
上下文。因此,如果你调用(5),你就把这个号码作为一个对象传递
调用
函数不提供参数,您给出的第一个参数是此
的上下文。通常,如果您希望它在上下文中,您可以给它{}
因此dis.call({})
,这意味着函数中的this
是空的this
。但是,如果您传递5
,它似乎将被转换为一个对象。看
所以返回值是object
执行five*5
时,JavaScript将对象five
视为基本类型,因此相当于5*5
。有趣的是,do'5'*5
,它仍然等于25
,因此JavaScript显然是在幕后操纵此行未对基础five
类型进行任何更改
但是当您执行
++
操作时,它会将对象转换为原语数字
类型,从而删除.wtf
属性因为您影响的是基础类型有两种不同的方式来表示数字:
var a = 5;
var b = new Number(5);
第一个是基元,第二个是对象。对于所有意图和目的,它们的行为都是相同的,只是在打印到控制台时它们看起来不同。一个重要的区别是,作为一个对象,newnumber(5)
像任何普通的{}
一样接受新属性,而原语5
不:
a.foo = 'bar'; // doesn't stick
b.foo = 'bar'; // sticks
至于首字母dis.call(5)
部分,请参见。让我们假设call
的第一个参数被用作this
的值,并且该操作将数字强制转换为更复杂的number
对象形式。*稍后++
将其强制转换回原语形式,因为加法操作+
会生成一个新的原语
> five = dis.call(5) // for all intents and purposes same as new Number(5)
Number {[[PrimitiveValue]]: 5}
> five.wtf = 'potato'
"potato"
> five.wtf
"potato"
Number
对象接受新属性
> five++
++
产生一个新的原语6
值
> five.wtf
undefined
> five.wtf = 'potato?'
"potato?"
> five.wtf
undefined
…不具有且不接受自定义属性
*请注意,在严格模式下,
此
参数的处理方式会有所不同,不会转换为数字
。有关实现的详细信息,请参阅。首先,看起来这是通过nodejs控制台运行的
一,
创建函数dis(),但由于未将其设置为var
,因此没有返回值,因此输出为undefined
,即使定义了dis()
。另一方面,此
没有返回,因为函数没有执行
二,
这将返回javascript的Number
对象,因为您只需将函数dis()
的This
值设置为原语5
三,
第一个返回“potato”
,因为您刚刚将five
的属性wtf
设置为“potato”
。Javascript返回您设置的变量的值,这样可以很容易地链接多个变量并将它们设置为相同的值,如下所示:a=b=c=2
四,
这将返回25
,因为您刚刚将原始数5
乘以5
。five
的值由Number
对象的值确定
五,
我以前跳过了这一行,因为我会在这里重复它。
它只返回您在上面设置的属性wtf
的值
六,
正如@Callum所说,+
将从对象number{[[PrimitiveValue]]:5}
中的相同值将类型转换为number
现在,因为five
是一个数字
,所以在执行以下操作之前,您不能再为其设置属性:
five = dis.call(five)
five.wtf = "potato?"
或
还请注意,第二种方法的行为与第一种方法不同,因为它定义的是通用对象,而不是以前创建的Number
对象
我希望这会有所帮助,javascript喜欢假设一些事情,因此当从Number
对象更改为基元Number
时,它可能会变得混乱。
您可以使用typeof
关键字write来检查某物的类型
五类
初始化之后,它返回'object'
,执行five++
之后,它返回'number'
@deceze非常好地描述了数字对象和原语数字之间的差异。原语值不能有属性。但当您尝试访问基元值上的属性时,它会透明地转换为临时数字对象 因此:
声明函数
dis
。函数返回其上下文
function dis() { return this }
undefined
使用上下文5
调用dis
。在严格模式()中作为上下文传递时,基元值被装箱。所以five
现在是object(装箱编号)
声明wtf
正确
five * 5
five.wtf
five++
five = dis.call(five)
five.wtf = "potato?"
five = { value: 6, wtf: "potato?" }
> function dis() { return this }
undefined
// Like five.dis(), so dis return the temporaty Number object and
// reference it in five
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
// Write the wtf attribut on the Number object referenced by five
> five.wtf = 'potato'
"potato"
// Read the wtf attribut on the Number object referenced by five
> five.wtf
"potato"
// Return 5*5 but dont change the reference of five
> five * 5
25
// Read the same wtf attribut on the Number object referenced by five
> five.wtf
"potato"
// Change the five reference to a new primitive value (5+1). Five
// reference a primitive now.
> five++
5
// Read the wtf attribut on a new temporary Number object construct from
// the primitive referenced by five. So wtf does not exist.
> five.wtf
undefined
// Write the wtf attribut on a new temporary Number object construct from
// the primitive referenced by five. But this object not referenced by
// five. It will be lost.
> five.wtf = 'potato?'
"potato?"
// Read the wtf attribut on a new temporary Number object construct from
// the primitive referenced by five. So wtf does not exist.
> five.wtf
undefined
> five
6
function dis() { return this }
undefined
five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
five.wtf = 'potato'
"potato"
five.wtf
"potato"
five * 5
25
five.wtf
"potato"
five++
5
five.wtf
undefined
five.wtf = 'potato?'
"potato?"
five.wtf
undefined
five
6
01 > function dis() { return this }
02 undefined
03 > five = dis.call(5)
04 Number {[[PrimitiveValue]]: 5}
05 > five.wtf = 'potato'
06 "potato"
07 > five.wtf
08 "potato"
09 > five * 5
10 25
11 > five.wtf
12 "potato"
13 > five++
14 5
15 > five.wtf
16 undefined
17 > five.wtf = 'potato?'
18 "potato?"
19 > five.wtf
20 undefined
21 > five
22 6
> function dis() { "use strict"; return this }
> five.valueOf = function () { return 10 }
undefined
> five * 5
50
var obj = { a : 1 };
var string = 'mystr' + obj;
var number = 3 + obj;
five = dis.call(5)
five.wtf = 'potato'
five * 5
five++
five.wtf
five.wtf = 'potato?'
five.wtf
(new Number(6)).wtf;
(new Number(6)).wtf = 'potato?';
(new Number(6)).wtf;
(new Number(3) === 3) // returns false
(new Number(3) == 3) // returns true, as the '==' operator coerces
(+new Number(3) === 3) // returns true, as the '+' operator coerces
> function dis() { return this }
undefined
> five = dis.call(5)
[Number: 5]
> five.wtf = 'potato'
'potato'
> five.wtf
'potato'
> five * 5
25
> five.wtf
'potato'
> five++
5
> five.wtf
undefined
> five.wtf = 'potato?'
'potato?'
> five.wtf
undefined
> five
6
> function dis() { return this }
undefined
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
> five.wtf = 'potato'
"potato"
> five.wtf
"potato"
> five * 5
25
> five.wtf
'potato'
> five++
5
> num = 5
5
> num++
5
>num
6
>five
6
> five.wtf
undefined
> five.wtf = 'potato?'
'potato?'
> five.wtf
undefined