The difference is that reproject changes the geometry coordinates. ---- Let me start with a Point layer, with one feature, wich geometry is a point located in _latitude = 1°_, _longitude = 2°_. The geometry WKT is `POINT ( 1 2 )` and the layer is defined with CRS `EPSG:4326`. And I have a custom projected CRS which map those coordinates to _x = 2000m_, _y = 1000m_. If I reproject the layer to my custom CRS, the new geometry WKT will be `POINT (2000 1000)`, and the new layer will be defined with my custom CRS (e.g, `CUSTOM:100001`). ---- If I assign my custom CRS to the source layer without reproject it, the geometry WKT of the feature will remain `POINT ( 1 2 )`, but the layer will be defined in `CUSTOM:100001` CRS. And in that CRS, _x = 1m_, _y = 2m_ represent a point far away from my source point. ---- In QGIS 3, the project CRS is the QGIS 2 _on-the-fly_ reprojection feature. If the project has a CRS defined, all the layers will be reprojected on-the-fly to that CRS before show them in the map. Yo can set _No projection_ for the project CRS in its properties, and the layers will be shown in their own CRS. In that case, both geometries `POINT ( 1 2 )` will be shown aligned, altought they are located in different places of the Earth. And `POINT ( 2000 1000 )` geometry will be shown far away from the source point, altought they are the same point but defined in different CRS. ---- _Save layer as_, when the target CRS is not the same as the source one, implies a _Reprojection_. _Assign_ and _Define_ I think is the same, change the layer CRS without change the geometry coordinates.