A node will have inner sep
unless you make it zero yourself, where as a co-ordinate doesn't. And further a node
doesn't create a geometric point. Your code with all inner sep=0
will give
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\begin{scope}[red]
\coordinate (a) at (0,0);
\node[inner sep=0,below=of a,draw] (anode) {};
\draw[-|] (anode) -- (a);
\node[inner sep=0] (b) at (.3,0) {};
\node[inner sep=0,below=of b,draw] (bnode) {};
\draw[-|] (bnode) -- (b);
\end{scope}
\begin{scope}[green,dashed]
\coordinate (a) at (0,0);
\node[inner sep=0,on grid,below=of a,draw] (anode) {};
\draw[->] (anode) -- (a);
\node[inner sep=0] (b) at (.3,0) {};
\node[inner sep=0,on grid,below=of b,draw] (bnode) {};
\draw[->] (bnode) -- (b);
\end{scope}
\end{tikzpicture}
\end{document}

Note that the horizontal red line on right is lower than that on the left even though the inner sep
is set to zero. (changing \node[inner sep=0] (b) at (.3,0) {};
to \coordinate (b) at (.3,0);
will fix it and this is one option to get things right.)
Replacing
\coordinate (a) at (0,0);
with
\node[inner sep=0cm] (a) at (0,0) {};
inside the scope, gives
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\begin{scope}[red]
\coordinate (a) at (0,0);
%\node[] (a) at (0,0) {};
\node[inner sep=0,below=of a,draw] (anode) {};
\draw[-|] (anode) -- (a);
\node[inner sep=0] (b) at (.3,0) {};
\node[inner sep=0,below=of b,draw] (bnode) {};
\draw[-|] (bnode) -- (b);
\end{scope}
\begin{scope}[green,dashed]
%\coordinate (a) at (0,0);
%\node[] (a) at (0,0) {};
\node[inner sep=0cm] (a) at (0,0) {};
\node[inner sep=0,on grid,below=of a,draw] (anode) {};
\draw[->] (anode) -- (a);
\node[inner sep=0] (b) at (.3,0) {};
%\coordinate (b) at (.3,0);
\node[inner sep=0,on grid,below=of b,draw] (bnode) {};
\draw[->] (bnode) -- (b);
\end{scope}
\end{tikzpicture}
\end{document}

Without inner sep = 0
we will get,
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\begin{scope}[red]
\coordinate (a) at (0,0);
\node[below=of a,draw] (anode) {};
\draw[-|] (anode) -- (a);
\node[] (b) at (.3,0) {};
% \coordinate (b) at (.3,0);
\node[below=of b,draw] (bnode) {};
\draw[-|] (bnode) -- (b);
\end{scope}
\begin{scope}[green,dashed]
%\coordinate (a) at (0,0);
%\node[] (a) at (0,0) {};
\node (a) at (0,0) {};
\node[on grid,below=of a,draw] (anode) {};
\draw[->] (anode) -- (a);
\node (b) at (.3,0) {};
%\coordinate (b) at (.3,0);
\node[on grid,below=of b,draw] (bnode) {};
\draw[->] (bnode) -- (b);
\end{scope}
\end{tikzpicture}
\end{document}

Option -2 Replacing \node[inner sep=0] (b) at (.3,0) {};
to \coordinate (b) at (.3,0);
in your code gives
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\begin{scope}[red]
\coordinate (a) at (0,0);
\node[below=of a,draw] (anode) {};
\draw[-|] (anode) -- (a);
\coordinate (b) at (.3,0);
\node[below=of b,draw] (bnode) {};
\draw[-|] (bnode) -- (b);
\end{scope}
\begin{scope}[green,dashed]
\coordinate (a) at (0,0);
\node[on grid,below=of a,draw] (anode) {};
\draw[->] (anode) -- (a);
\coordinate (b) at (.3,0);
\node[on grid,below=of b,draw] (bnode) {};
\draw[->] (bnode) -- (b);
\end{scope}
\end{tikzpicture}
\end{document}

I do not see why this is not the case:
When you say above=1cm of somenode with on grid set to true, the new node will be placed in such a way that its center is 1cm above the
center of somenode.
The only non-standard thing in my example is that then reference node
is a coordinate, but I do not see why it results in the observed
behavior, as this is just a node with only a center.
And I don't know how to answer this, with all the above facts. May be some experts will shed light on this.