For the 1st case, in the constructor body, the unqualified names are always found in the constructor scope and refer to the constructor parameters. Then name lookup stops, the further scope including class scope won't be examined. Then when you want to specify data members you have to qualify explicitly like this->name, otherwise, name = name; means assigning name by itself.
For the 2nd case, data members are initialized (btw this is not assignment as the 1st case) by member initializer list. From [class.base.init]/2,
(emphasis mine)
In a mem-initializer-id an initial unqualified identifier is looked up in the scope of the constructor's class and, if not found in that scope, it is looked up in the scope containing the constructor's definition. [ Note: If the constructor's class contains a member with the same name as a direct or virtual base class of the class, a mem-initializer-id naming the member or base class and composed of a single identifier refers to the class member. A mem-initializer-id for the hidden base class may be specified using a qualified name. — end note ] Unless the mem-initializer-id names the constructor's class, a non-static data member of the constructor's class, or a direct or virtual base of that class, the mem-initializer is ill-formed.
That means, the mem-initializer-id will be looked up in the scope of the class, it won't and can't refer to the constructor parameter.
On the other hand, [class.base.init]/15,
Names in the expression-list or braced-init-list of a mem-initializer are evaluated in the scope of the constructor for which the mem-initializer is specified.
The names in initializer expression are looked up in the scope of the constructor, then constructor parameters are found. So name(name) means initializing the data member name by the constructor parameter name.