What you do within your code is:
[object] $x = 'abc', 'def'
==> The type of 'abc' and 'def' is [System.String]. Because you comma seperated them PowerShell does automatically create a list. So after executing that line $x is a System.Object[]. Index 0 and 1 contains [System.String].
$x = $null;
==> Now you define $null as the value for $x. So you are removing the value. The type of $x is now undefinded. You can set the value 123 then $x will become type System.Int32. You can redefine a string and so on.
Within your for-loop you use
$x += 'somestring' + $addingSomeStuff + 'otherstring'
==> The result here is that within the first Iteration of the for-loop PowerShell will assign a String to $x. So the type of $x will be [System.String]. In the next iterations the += operator adds additionally content to the value of $x, which is still [System.String]
Don't set $x to $null. Because you'll loose the type information. For more information read about the PowerShell Extended Type System.
The following snippet works. Hope that helps.
############################################
# The following was not part of your post #
# I added it to get it run in general #
$numberOfColumns = 2
$NamesOfColumns = 'Column1', 'Column2'
############################################
[object] $x = 'abc','def';
# don't set $x to $null
# define an empty list instead ;-)
$x = @()
for ($i = 0; $i -lt $numberOfColumns; $i++) {
$x += '$_.' + $NamesOfColumns[$i] + '.Trim()';
}