Title: Creating Constructors with JavascriptCore
Tags: javascript;ios;objective-c;c;xcode
Question: When using the ```JavascriptCore API```, I'm not sure how to create new instances of Objective-C objects from Javascript via the ```new``` syntax ```(ex. var x = new MyAwesomeClass())```. It seems like the constructor objects that are created in Javascript when passing in an Objective-C class that conforms to a ```JSExport-derived protocol``` should be callable as constructors, but they are not.

For example, say I delcare a class that conforms to a ```JSExport-derived protocol``` and I insert it into the javascript context as such:

```     @protocol MyAwesomeClassExports <JSExport&gt;
    ...
    @end

    @interface MyAwesomeClass : NSObject <MyAwesomeClassExports&gt;
    ...

    @end



   JSContext *context = ...;
context[@"MyAwesomeClass"] = [MyAwesomeClass class]
```

Then, if I try to make a new instance in javascript via a syntax such as this:

```[object MyAwesomeClassConstructor] is not a constructor
```

Is it possible to make new instances of Objective-C objects from javascript using the ```new``` syntax? What I would ideally like is for it to ```alloc``` and then call the ```init``` method on my Objective-C instance. If any arguments were passed in javascript those would hopefully be accesible in the Objective-C ```init``` method via the [JSContext currentArguments] class method.


Here is the accepted answer: This question was asked the other day in the Apple Developer Forums, here.  

From what I can tell, it looks as if this is a known deficiency that was only fixed recently in WebKit (which includes JavaScriptCore); and the change isn't in iOS7:

https://bugs.webkit.org/show_bug.cgi?id=123380

It might be possible to accomplish this externally to WebKit though by using JSObjectMake and a properly configured JSClassDefinition?  I haven't had time to investigate this route. 


Here is another answer: Create a protocol for the class you want to instantiate from Javascript. It should extend JSExport.

```@import JavaScriptCore

@protocol EntityExports <JSExport&gt;

@property NSString *somePropertyToExpose
- (instancetype)initWithSomeValue:(NSString *)value;

@end

@interface Enity : NSObject <EntityExports&gt;
@end
```

and in the .m file, implement the initializer and synthesize the property:

```@implementation Entity

@synthesize somePropertyToExpose = _somePropertyToExpose;

- (instancetype)initWithSomeValue:(NSString *)value
{
// implementation goes here
}

@end
```

Then, in your code that instantiates the JSContext:

```context[@"Entity"] = [Entity class];
```

and to instantiate an ```Entity``` in Javascript:

```var entity = new Entity("hello!");
```

(note that the property is not necessary for constructing the object; it is just there to make the example non-trivial).

Comment for this answer: Its worth noting that you can only have one initialiser in the JSExported class, multiple initialisers are discarded (see the above patch).

Here is another answer: I know this is really old, but this is what works for me:

```context[@"MyClass"] = ^MyClass*{
    return [[MyClass alloc] init];
};
```

Then from JavaScript:

```var myClass = new MyClass();
```


Here is another answer: An easy solution is to define a constructor function in Obj-C.

```// Inside protocol
+ (MyAwesomeClass *)create;
...

// Inside implementation
+ (MyAwesomeClass *)create
{
  return [[MyAwesomeClass alloc] init];
}
```

Then in JavaScript, simply call this constructor to create a new object:

```obj = MyAwesomeClass.create()
```

Comment for this answer: This helped me out. Good answer.

Here is another answer: I'm not sure this but I think you should create your Objective-C object first and after that you should create JSValue like this:

```MyAwesomeClass *myClass = [[MyAwesomeClass alloc] init];
JSValue *dataValue = [JSValue valueWithObject: myClass inContext:context];
```

Let me know is this help.


Here is another answer: This is what i've been using. Hope this helps!

```extern void RHJSContextMakeClassAvailable(JSContext *context, Class class){
    NSString *className = NSStringFromClass(class);
    context[[NSString stringWithFormat:@"__%@", className]] = (id) ^(void){ return [[class alloc] init]; };
    [context evaluateScript:[NSString stringWithFormat:@"var %@ = function (){ return __%@();};", className, className]];

    //allow a class to perform other setup upon being loaded into a context.
    SEL selector = NSSelectorFromString(@"classWasMadeAvailableInContext:");
    if ([class respondsToSelector:selector]){
        ((void (*)(id, SEL, JSContext*))[class methodForSelector:selector])(class, selector, context);
    }
}
```

Comment for this answer: When using this, class methods can be accessed because the Constructor does not contain the correct prototype. This causes class methods to be unaccessable. The code does work for the constructor creation though.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 6, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2013:00:11/21/13', 'FavoriteCount': 3.0, 'PostTypeId': 1, 'Tags': '<javascript><ios><objective-c><c><xcode>', 'Title': 'Creating Constructors with JavascriptCore', 'ViewCount': 2439, 'id': 20113799, 'user_AboutMe': '<p>Think Different...</p>\n', 'user_AccountId': 1815648.0, 'user_DisplayName': 'codercat', 'user_Reputation': 22417.0, 'user_Views': 2062.0, 'user_id': 1650785.0}}