\def and \let are TeX primitves and their use is discouraged.

The usage of TeX primitives will often result in unwanted behaviour, especially when the exact workings are not known.

\def is a TeX primitive, \newcommand is a LaTeX overlay on top of \def. The most obvious benefits of \newcommand over \def are:

  1. \newcommand checks whether or not the command already exists
  2. \newcommand allows you to define an optional argument

In general, anything that \newcommand does can be done by \def, but it usually involves a little trickery and unless you want something that \newcommand can't do, there's no point in reinventing the wheel.