0

I want to restrict access to certain things in the JavaScript language from the outside. I've done some research on this, but I haven't been able to get anything I want. I know the underscore doesn't provide complete protection. When I try to reach from outside, I can easily reach. I'm going to write a sample code.

  function Car(){
    this._mileage = 0;
  }

  Car.prototype.drive = function(miles){
    if(typeof miles == 'number' && miles > 0){
      this._mileage += miles;
    }else{
      throw new Error("Sadece pozitif sayılar girin");
    }
  };

  Car.prototype.readMileage = function(){
    return this._mileage;
  }
  
  var hondo = new Car();
    console.log('old: '+hondo._mileage);
  hondo._mileage = 100;
  console.log('new: '+hondo._mileage);

As you can see: Although I used underscores, I could easily access from outside the classroom.

Another method

I found a method in my research. But I don't quite understand that either.

  var Car = (function(){
    var _ = PrivateParts.createKey(); // createKey = ?

    function Car(mileage){
      _(this).mileage = mileage;
    }
    Car.prototype.drive = function(miles){
      if( typeof miles == 'number' && miles > 0){
        _(this).mileage += miles;
      }else{
        throw new Error('drive only accepts positive numbers');
      }
    }
    Car.prototype.readMileage = function(){
      return _(this).mileage;
    }
    return Car;
  }());

4
  • 1
    What do you mean by "from outside of the javascript language"? Commented Apr 20, 2019 at 8:49
  • Which "certain things" do you want to protect, and from whom? Commented Apr 20, 2019 at 8:50
  • 1
    I want to prevent the user from accessing some code. For example; Consider a code that prevents the speed from falling below 0. Let the user enter only the speed value. Just reach that value. Other than that, cannot change anything else inside the class.(example) Commented Apr 20, 2019 at 14:17
  • 1
    What do you mean by "user"? The end user running the code? The end user viewing the web page? The programmer using your code? The program using your object? Notice that any of them could alter your object to do whatever they want, you cannot control it. Commented Apr 21, 2019 at 15:23

2 Answers 2

0

Your second code is generally on the right track, though you need to define privateParts as something first. It also seems a bit too complicated at the moment.

The idea is to save the variable in a closure; due to normal scoping rules, a variable can't be accessed outside where it's defined:

const fn = (() => {
  const foo = 'foo';
  return () => 'foo is: ' + foo;
})();

// at this point, the contents of the "foo" variable are not visible to the outside,
// you can only call the deliberately exposed function:
console.log(fn());

Similarly, with a class, you can save all properties you want to keep private in an Map indexed by the instance used: keep the Map scoped to just the class, and not the outside, and everything you put on the Map won't be visible to the outside:

const Car = (() => {
  const map = new WeakMap();
  return class Car {
    constructor(mileage) {
      map.set(this, { mileage });
    }
    drive(miles) {
      if (typeof miles == 'number' && miles > 0) {
        map.get(this).mileage += miles;
      } else {
        throw new Error('drive only accepts positive numbers');
      }
    }
    readMileage() {
      return map.get(this).mileage;
    }
  }
})();

var hondo = new Car(50);
console.log('old: '+hondo._mileage);
hondo._mileage = 100;
console.log('new: '+hondo._mileage);
console.log(hondo.readMileage());
hondo.drive(100);
console.log('newer: '+hondo._mileage);
console.log(hondo.readMileage());

The Map is basically just an object indexed by each this (each instance of Car). Because its values can only be retrieved inside the Car closure, it's an effective way of making sure the information is not exposed to the outside.

That said, this doesn't prevent clients from looking at your source code - no client-side code is truly private. If you have sensitive information, you should only send it to the client in the first place if they have to know it. Using a technique like this will not prevent the client from looking at your code and possibly intercepting information sent. (Nefarious scripts can do something similar, especially if given the opportunity to run before your script runs.) So what this implements isn't so much confidential, so much as it provides reasonable but not airtight restrictions on how other well-behaved scripts can access data.

Sign up to request clarification or add additional context in comments.

Comments

0

It's called an IIFE (Immediately Invoked Function Expression) and it means that the private key you make with PrivateParts.createKey will never ever be accessible outside of the function, because the code inside the IIFE is run, then it ends. Because of the way you have defined it, you now have a completely unique key that cannot be accessed from anywhere. That being said, it's still very insecure to do any key or encryption work on the client side - use PHP, Node.JS, or another server-side language to fully protect your data.

Comments