It's more than just see uncommitted values that can be inconsistent. You may also fail to read committed data, because it was being moved or in a page split when you scanned the table. Or you may read the same data twice due to the same reason.
When you use NOLOCK and SQL Server scans a table, it may use an IAM scan, which is more efficient, but which is not safe for things like I mentioned above.
NOLOCK can be very useful for ad-hoc queries in a production system to avoid blocking, and particularly to investigate the progress of long-running transactions.
But it very rarely has a place in application code, since the risk for transient incorrect results is too high. If blocking is a concern, using some form of snapshot is better.