Edit in JSFiddle

// Sort an array of objects interdependent on one or more of
// its key values. The initial array will not be mutated,
// unless you re-assign it
//
// syntax
// ------
// const sorted = XSort().create([arrOfObjects])
//  .orderBy(
//		{key: [keyname], [descending=0/1] }, 
//		{key: [keyname], [descending=0/1]} );
// Can use lambda methods for the keys that should be sorted
// so if the value is an object, something like
//   [xsort].orderBy({key => key.firstName.startsWith("J")}, {[...]}, ...)
( d => {
	const booksArray = getData();
  const booksSorted = XSort()
      .create(booksArray)
      .orderBy( { key: 'Rate' }, { key: 'Price', descending: 1 } );
  
  d.querySelector("pre").textContent = JSON.stringify( booksSorted, 	null, " " );
  
  function XSort() {
    const multiSorter = sortKeys => {
      if (!sortKeys || sortKeys[0].constructor !== Object) {
        throw new TypeError("Provide at least one {key: [keyname]} to sort on");
      }
            
      return function (val0, val1) {
        for (let sortKey of sortKeys) {
          const v0 = sortKey.key instanceof Function ? sortKey.key(val0) : val0[sortKey.key];
          const v1 = sortKey.key instanceof Function ? sortKey.key(val1) : val1[sortKey.key];
          const isString = v0.constructor === String || v1.constructor === String;
          const compare = sortKey.descending ?
            isString ? v1.toLowerCase().localeCompare(v0.toLowerCase()) : v1 - v0 :
            isString ? v0.toLowerCase().localeCompare(v1.toLowerCase()) : v0 - v1;
          if ( compare !== 0 ) { return compare; }
        }
      };
    }
    const Sorter = function (array) {
      this.array = array;
    };
    
    Sorter.prototype = {
      orderBy: function(...sortOns) {
        return this.array.slice().sort(multiSorter(sortOns));
      },
    };

    return {
      create: array => new Sorter(array)
    };
  }

  function getData() {
    return [
      {Rate:3, Id:16, Price:200, Name:"Functional Programming"},
      {Rate:5, Id:1, Price:200, Name:"History"},
      {Rate:5, Id:2, Price:150, Name:"Geographic"},
      {Rate:2, Id:17, Price:190, Name:"Computer Science"},
      {Rate:3, Id:15, Price:250, Name:"Jihad"},
      {Rate:1, Id:3, Price:75, Name:"Maths"},
      {Rate:3, Id:7, Price:110, Name:"Chemistry"},
      {Rate:2, Id:4, Price:50, Name:"Statistics"},
      {Rate:2, Id:6, Price:100, Name:"Arts"},
      {Rate:4, Id:10, Price:80, Name:"Algorithm"},
      {Rate:1, Id:11, Price:85, Name:"Urdu"},
      {Rate:4, Id:8, Price:160, Name:"Biology"},
      {Rate:1, Id:13, Price:120, Name:"Physics"},
      {Rate:3, Id:14, Price:230, Name:"Electronics"},
      {Rate:3, Id:5, Price:120, Name:"Drawing"},
      {Rate:2, Id:18, Price:50, Name:"Problem solving Techniques"},
      {Rate:6, Id:19, Price:150, Name:"C#"},
      {Rate:7, Id:20, Price:250, Name:"ASP.Net"},
      {Rate:1, Id:12, Price:110, Name:"International Relations"},
      {Rate:4, Id:9, Price:90, Name:"Software Engineering"},
    ];
  }
  
})(document);
<div class="solink" data-linkid="25157510">
    <div class="linkhover">loading....</div>
</div>
<div id="result">
  <code>data</code> ordered by Rate 
  <i>and</i> Price descending 
  (using <code>xSort.orderBy)</code>
</div>
<pre></pre>