Class.isClass

Hi Friends, what you think about to add to new standard the Class.isClass
actually exists the Array.isArray....

What is Class?

If you’re meaning to suggest every type have an “isWhatever” function on it, that’s been rejected in the past.

If you intend to see if a particular object has been defined with the class keyword, you could look at its implementation, namely C.toString().startsWith('class'). But don’t do that: an object may have the functionality of a class without being defined with the class keyword.

SpiderMonkey once had a Function.prototype.isGenerator() method. It gave you a correct but unintuitive answer when .bind() was used around a generator function.

Another reason not to do that because it could result in false positives

(classes => classes).toString() // "classes => classes"

typeof C === 'function' && Function.prototype.toString.call(C).startsWith('class')

oh, but, actually, the Array.isArray exists, why?

That's the only one that exists - it's because instanceof Array fails for cross-realm arrays (like, from an iframe), and it was intended to be a replacement for it for that use case. Unfortunately, it was not extended into a general mechanism.

friend, but, if the Array.isArray exists, then, for mathematical coherence, in the new ES6 Classes is needed to incorporate the Class.isClass, to determine if an object contains a class or not.
"to clarify and normalize the language, and of course gain performance"
Why appeal to ugly routines to achieve it?
i actually use:
function isClass(val)
{
return typeof val === "function" && /^\s*class\s+/.test(val.toString());
}

That kind of consistency argument has been tried, and the committee resoundingly rejected it.

i see

Why are you trying to distinguish classes from other objects? This isn't really possible to do in javascript.

For example:

function MyThing() {
  const instance = Object.create(MyThing.prototype)
  Object.assign(instance, { x: 2, y: 3 })
  return instance
}

// MyThing is a class
const instance = new MyThing()
console.log(instance)

// MyThing is also a factory function
const instance2 = MyThing()
console.log(instance2)

The MyClass() function above is both a class and a factory function. There's nothing that can be done, even by the javascript language, to know weather or not that function is intended to be a class or not.

Or - maybe you're not trying to check if something is a class per-say, but are just trying to check if whatever you received was created using the es6 class syntax? Even this is dangerous to do - transpilers will automatically change classes made with es6 syntax into normal functions, and this isClass() function might not ever return true.

1 Like

Hi Scotty, i mean about the classes of ES6 or later.

Why are you trying to distinguish classes from other objects?
Sometimes is need to distinguish to decide either to cast a new instances of this or not,
this is common task in some frameworks, like ex: to apply skins etc
Imagine you can store a es6 class (the real class) inside a object variable, and later, with this, then cast a new instance calling these.

if isClass(val) -> new val

I think that the best thing to do is to test whether your value is a function object, with:

typeof val === "function"

The test will pass for all constructors (including “classes”). That means, of course, that the user is not supposed to provide a function object that is not a constructor.

1 Like

Another option here is to use a protocol. It sounds like what you're really wanting to know is whether or not the provided value implements some "casting" interface. (Not all classes would implement this behavior you're describing). So, if the provided value does implement it, then do one action, if they don't, then do another.

This duck-typing can be as simple as requiring anyone who implements this interface to have an explicit "cast" function on it. If it exists, then do your casting.

Or, to make it more robust, you can use a symbol:

const cast = Symbol('Cast Protocol')

class Point {
  constructor(x, y) {
    this.x = x
    this.y = y
  }

  static [cast](somethingToCastFrom) {
    const { x, y } = someCastingLogic(somethingToCastFrom)
    return new Point(x, y)
  }
}

function castIfAble(value, CastClass = null) {
  // Does it implement the cast protocol?
  if (CastClass[cast]) {
    // Then use it
    return CastClass[cast](value)
  } else {
    // Otherwise, don't do any casting
    return value
  }
}
1 Like

scoty, I really appreciate your comment, but personally I think it is a very dirty solution ;)

You can new normal functions, and you can't new every class (for example, class C { constructor() { if (new.target === C) { throw new Error('must be a subclass'); } } }).

1 Like

Friend, you think in functions, but, i talk about es6 classes.
The old way (funcion) is obsolete (I'm not looking to open a debate)
Lets talk classes from es6 onwards

That’s how I’d describe “trying to generically determine if you can construct a value” ¯_(ツ)_/¯

It is not obsolete, it’s functionality that will exist forever and must work forever. A mechanism to determine constructability that ignores normal functions is broken and would not be acceptable in the language, full stop.

2 Likes