不经意间想起了一道很久前在学校同学间曾经多次讨论的一个程序细节问题,甚至作为评价是否头脑灵活的一种方式:
?
x,y两整数交换值的方法
?
1. 中间变量
最常用的,刚开始学习就被灌输了这个思想:
z=x;
x=y;
y=z;
?
2.c学习时期,又接触了节省空间的做法
x=x+y;
y=x-y;
x=x-y;
3.c时期的终极解法,已然作为一种传奇
x=x^y;
y=x^y;
x=x^y;
4.但是在 javascript中存在最 简洁的两数交换(只在firefox中可用)
[x,y]=[y,x]
ps:占位符,疑惑的规范,尚不明白待细查
尚不太明确规范在何处规定这一行为,摘要一段关于赋值的描述:
?
只在firefox中可用,晕,规范没说
LeftHandSideExpression = AssignmentExpression
1.Let lref be the result of evaluating LeftHandSideExpression.
2.Let rref be the result of evaluating AssignmentExpression.
3.Let rval be GetValue(rref).
4.Throw a SyntaxError exception if the following conditions are all true:
?Type(lref) is Reference is true
?IsStrictReference(lref) is true
?Type(GetBase(lref)) is Enviroment Record
?GetReferencedName(lref) is either "eval" or "arguments"
5.Call PutValue(lref, rval).
6.Return rval.
主要是 GetValue ,PutValue 两个操作不太明白,赋值应该是在 5步 PutValue 中考虑了这种情况:
PutValue(V,W):
1.If Type(V) is not Reference, throw a ReferenceError exception.
2.Let base be the result of calling GetBase(V).
3.If IsUnresolvableReference(V), then
a.If IsStrictReference(V) is true, then
i.Throw ReferenceError exception.
b.Call the [[Put]] internal method of the global object, passing GetReferencedName(V) for the property name, W for the value, and false for the Throw flag.
4.Else if IsPropertyReference(V), then
a.If HasPrimitiveBase(V) is false, then let put be the [[Put]] internal method of base, otherwise let put be the special [[Put]] internal method defined below.
b.Call the put internal method using base as its this value, and passing GetReferencedName(V) for the property name, W for the value, and IsStrictReference(V) for the Throw flag.
5.Else base must be a reference whose base is an environment record. So,
a.Call the SetMutableBinding (10.2.1) concrete method of base, passing GetReferencedName(V), W, and IsStrictReference(V) as arguments.
6.Return.
此时 V是左值引用, V的base是environment record?? W是右值,那么就执行 SetMutableBinding 这个操作,已经看不太明白了。
?
?
x=x^y;
y=y^x;
x=x^y;
吧
x=x^y;
y=y^x;
x=x^y;
吧
额,笔误笔误