In DOS 5.0+ (at least, never tried it on earlier) and probably every version of Windows DOS's EXEC and Windows' CreateProcess()/LoadLibrary() does not care about the filename and just uses loader implementation appropriate for whatever was detected from the header.
ShellExecute() (and it's DOS "equivalent" EXEC(%COMSPEC%, "/C foo")) does care about the extension. In DOS there is hardcoded list of extensions that are executable (BAT, COM, EXE, in this order, with BAT being handled by the command.com itself. There is no way to directly execute image with different extension from the command line), while in Windows what happens depends on contents of HKCR.
One notable feature of how this is handled by DOS is that when you have both foo.exe and foo.com then foo.com takes precedence (IIRC this has something to do with the fact that traditional Windows entrypoint was called WIN.COM although it always was MZ binary).