Why do I have to assign an exported constructor, before I can use it with the new operator to instantiate an object type?
For example (using npm package rss):
const feed1 = new require('rss'); // => errors out: this is undefined in constructor
const rss = require('rss'),
feed2 = new rss; // => works fine
As far as I understand Node's module system, require('rss') exposes the constructor. So why can't I use it "directly"?
I think this happens because you leave off the parentheses after the constructor. What internally happens is that node thinks of adding parentheses after the require() call – at least this is what it looks like:
const i = new require('rss') // results in an error
now, let's write it with parentheses instead:
const i = new require('rss')()
This does not work either, because in this case, node tries to evaluate require('rss')() first, and then executes new, because everything is evaluated from right to left.
Let's tell node now to not execute the rss exports, but instead properly create an instance:
const i = new (require('rss'))()
Related
What is the difference between
jasmine.createSpy('someMethod')
And
spyOn(someObject, 'someMethod')
And why should one choose to use spyOn?
My guess is that the first alternative will match the method someMethod no matter in what object it's contained but spyOn will only match if it's contained in someObject. Thus making createSpy just a more generic matcher?
The difference is that you should have a method on the object with spyOn
const o = { some(): { console.log('spied') } };
spyOn(o, 'some');
while the mock method is created for your with createSpy():
const o = {};
o.some = jasmine.createSpy('some');
The advantage of the spyOn is that you can call the original method:
spyOn(o, 'some').and.callThrough();
o.some(); // logs 'spied'
And as #estus says the original method is restored after the test in case of spyOn. This should be done manually when it's reassigned with.
Additionally to the other fine answer:
Use spyOn() to spy (intercept) an existing method on an object to track calls of other modules to it.
Use jasmine.createSpy() to create a function that can be passed as callback or Promise handler to track call-backs.
I have a fairly simple javascript method
(props,propName,componentName) => {
var value = props[propName];
const getOrSpread = name =>
props[name] || props.spread && props.spread[name];
// remainder of function code omitted
}
that is working in javascript land. I'm trying to convert it to fable but either I can get it to have a definitely exists property access to .spread or dynamic access to props[propName] but not both
module JsxHelpers =
type IReactProps =
abstract member spread : obj
let isfuncOrNullPropType (props:IReactProps) (propName:string) componentName =
let propsO :obj = box props
let value:obj = propsO?propName
let valueAttempt2:obj = (box props)?(propName)
// rest of translation not attempted yet
value
where if props is defined as IReactProps, then .spread works, but neither of the two possible let value lines compile.
or props is defined as obj and it says `This expression was expected to have type 'obj' but here has type ''a -> obj'
even the simplest object from the documentation doesn't appear to compile:
let isfuncOrNullPropType (props:obj) (propName:string) =
let value2:obj = props?propName
value2
using "fable-core": "^1.0.0-narumi-905"
You definitely need to put the prop name in parentheses according to the documentation. The compiler error you're getting is because props?(propName) returns type 'a -> obj. Apparently, the dynamic (?) operator returns an Applicable, and from the fable source:
/// DO NOT USE: Internal type for Fable dynamic operations
type Applicable = obj->obj
Perhaps try:
let value : obj = unbox<obj> (props?(propName))
In RxJx I am trying to update the 'Observable` But it not updating the value. I am keep getting the first declared values.
how to fix this?
here is my code :
const streamA$ = Rx.Observable.of(2);
const streamB$ = Rx.Observable.of(4);
streamA$ = Rx.Observable.of(10) //not updating!
const streamC$ = Rx.Observable.concat(streamA$, streamB$)
.reduce((x, y) => x + y);
streamC$.subscribe(function(x){
console.log( x );
}); //prints 6
//even from here i would like to update
streamA$ = Rx.Observable.of(10) //not updating!
You've declared streamA$ using const, and you subsequently attempt to reassign it. Doing this will cause the original value to be retained. If you want to reassign streamA$, you'll need to declare it using var. This is true of all javascript variables, and isn't peculiar to Rx.
I suspect what you actually want to do here is either combine streamA$ with another stream, or feed a value directly into streamA$ (in which case you'll need it to be a Subject of some kind).
I want to know whether this sentence is correct?
You can do:
var a = new A();
if and only if A is instanceof Function.
Simply you can create an instance of function and you know a function is an object. Why can't we create an instance of other user-defined objects? Like this:
var b={};
var c = new b(); //error
EDIT: How can I change b so that I can create an instance of that?
You can actually use Object.create() to have some sugar around ECMAscript's prototypal nature. Like
var b = { };
var c = Object.create( b );
Now, c will have b on its prototype chain. ECMAscript or more precisely, prototypal inheritance doesn't work exactly the same way as a "classical inheritance". By calling new when invoking a function, you actually receiving a newly created object aswell. You can modify and access that object via the this value within that such called constructor function.
However, you didn't inherit anything so far. You would need to create and fill the .prototype - object for your constructor function before you create instances of it. This pattern annoyed lots of people, so ES5 brought as a more convinient way to directly inherit from other objects using Object.create().
Simply you can create an instance of function and you know a function is an object. Why can't we create an instance of other user-defined objects?
It’s not quite correct to say “you can create an instance of function”. The new keyword is a bit misleading - it makes JavaScript look like it implements object-orientation using classes, when in fact it doesn’t.
What you’re actually doing with new A() is creating an object using the constructor function A. The new keyword tells the JavaScript interpreter to return an object from A - specifically the object referred to as this inside of A.
EDIT: How can I change b so that I can create an instance of that?
In your example, b is an object (var b={};). If you change b into a constructor function, then you can create objects using it. (By convention, constructor functions in JavaScript start with capital letters.)
So:
function B () {
}
var c = new B();
You can add things to the prototype object of B, and they’ll be accessible on c too (and on any other objects you create using B):
function B () {
}
B.prototype.NAME = 'B';
B.prototype.hello = function () {
alert('Hello!');
}
var c = new B();
c.NAME // 'B'
c.hello() // alerts 'Hello!'
Short answer: The new operator requires its operand to have a special internal method [[Construct]] that generic objects do not have.
Long answer:
11.2.2 The new Operator
The production NewExpression : new NewExpression is evaluated as follows:
1. Evaluate NewExpression.
2. Call GetValue(Result(1)).
3. If Type(Result(2)) is not Object, throw a TypeError exception.
4. If Result(2) does not implement the internal [[Construct]] method, throw a TypeError exception.
5. Call the [[Construct]] method on Result(2), providing no arguments (that is, an empty list of arguments).
6. Return Result(5).
The production MemberExpression : new MemberExpression Arguments is evaluated as follows:
1. Evaluate MemberExpression.
2. Call GetValue(Result(1)).
3. Evaluate Arguments, producing an internal list of argument values (11.2.4).
4. If Type(Result(2)) is not Object, throw a TypeError exception.
5. If Result(2) does not implement the internal [[Construct]] method, throw a TypeError exception.
6. Call the [[Construct]] method on Result(2), providing the list Result(3) as the argument values.
7. Return Result(6).
You can also do
var b = new a.constructor();
I'm trying to use boost::shared_ptr and boost::enable_shared_from_this to no avail. It looks as if shared_from_this() is returning the wrong shared_ptr. Here is what I see:
Task* task = new TaskSubClass();
boost::shared_ptr<Task> first = boost::shared_ptr<Task>(task); // use_count = 1, weak_count = 1
boost::shared_ptr<Task> second = first; // use_count = 2, weak_count = 1
boost::shared_ptr<Task> third = first->shared_from_this(); // use_count = 2, weak_count = 2
I also noticed that first.px = third.px but first.pn.pi != third.pn.pi. That is, they both share the same object but they use a different counter. How can I get the two to share the same counter?
Turns out that this was caused by the fact that TaskSubClass's constructor invoked some method that, in turn, invoked new boost::shared_ptr<Task>(this) instead of new boost::shared_ptr<Task>(shared_from_this()). As an added bonus, you're not supposed to invoke shared_from_this() from the constructor and the documentation is far from obvious on this point: There must exist at least one shared_ptr instance p that owns t. It makes sense in retrospect, but the documentation should really be more explicit :)
Sorry for the misleading question.