The purpose of un/serialize is to restore the same data you had before calling them, including class instances. This means you also have access to instance methods after deserialization. Functionality is provided so that you can implement handling of resources which cannot be serialized, such as recreating (in reality, creating new) file handles, database connections etc.
The purpose of json decode/encode is to transfer data in a compact format which can be easily parsed. But it only deals with data, not anything else related to instances. Thus, if you json_decode(json_encode($some_class_instance)), you retain data but no information about its methods. I.e. you lose information about which class was instantiated and get an array map / standard Object.
The difference between the two are
1. serialize will include all of the instantiated class' data, json_encode respects visibility
2. serialize can include all of the instantiated class' parent classes' data, if they implement Serializable
3. serialize will call _sleep - unless Serializable is implemented, then serialize is called - json_encode does not
4. unserialize will call __wakup - unless Serializable is implemented, then unserialize is called - json_decode does not
5. unserialize will recreate an instance of the original class, json_decode will either create an instance of Object or an associative array, depending on setting
6. json_encode creates character strings, serialize (may) create binary strings and must be treated as such.