extending an object with new functions in Javascript - javascript

Basically Dub and Dub.socialize objects already exist as an included library. I'm trying to extend the library with some additional custom functions that I created.
I attempted the following concept below:
Dub.socialize = {
setUID : function(preUID, postUID)
{
// .. function code here
}
}
However, I receive the following error "Uncaught TypeError: Cannot set property 'setUID' of undefined" from my console.
Obviously my knowledge of objects is a bit misled. What would be the proper method of extending this function into the already existing object library?

A simple solution could be
Dub.socialize.setUID = function(preUID, postUID) {};

Try this:
Dub.socialize.prototype.setUID = function(preUID, postUID) {
...
};
Object Constructor and prototyping
Edit: Realized you're working with a "static" object. This only works for something that is instantiated, and since you're not making new instances, this doesn't apply.

If you are going to create the function for declared object means then you have to use "prototype" keyword for example.
`var Dub = {
socialize: new Object()
};
Dub.socialize.prototype.setUID = function(preUID, postUID) {
// Function Body
};`
http://www.javascriptkit.com/javatutors/proto3.shtml

Related

Why can't I access my custom string prototype from an object method?

I have a custom string prototype that does some actions to a string;
String.prototype.norm_to_ascii=function(){return unescape(encodeURIComponent(this))};
In my example, the string that I want to apply the prototype to is a global object property that lives outside of the SampleObject object. In my actual code it would be referenced like this;
var userObject = {
name: "SomeName",
id: "SomeID"
}
It works everywhere in my project (other js files) except for within a particular Object method;
var SampleObject = { //This is in it's own js file called sampleobject.js
test: 0,
doStringThings {
let something = userObject.id.norm_to_ascii() //RETURNS userObject.id.norm_to_ascii is not a function
}
}
So in the SampleObject, I need to use the id, for example, but I need to do some basic decoding of the id value that is in the userObject which is what the string prototype does.
I can use this string prototype elsewhere. This is in a chrome extension so I have defined the prototype in the service worker and it can be used in the popup and content pages as well as the service worker so it must have to do with the object method but I can't figure out why?
Can anyone offer any suggestions to expose that prototype to the object method without having to redefine it?
EDIT
I should have been more clear in my explanation. I updated my example above.
You forget about this
this.otherTestValue.norm_to_ascii()
After seeing the updated question my conclusion is that you are defining the norm_to_ascii function after you run it.
Changing the order of the imports should fix the problem. Can you show us the structure of the project and where are you importing the file with that prototype?

Axios generic Post returns wrong type in TypeScript

I am trying to return a typed object using the Axios API. I am using the generic type to declare that I am returning an instance of GetSliceResponse but unfortunately Axios seems to still return an object of type any.
My code looks like this
export class GetSliceResponse
{
Success: boolean;
}
Axios.post<GetSliceResponse>("myurl/Get", request).then(o => {
var expectedResult = (new GetSliceResponse()) instanceof GetSliceResponse;
//expectedResult = true;
var unexpectedResult = o.data instanceof GetSliceResponse;
//unexpectedResult = false;
});
The Http response is exactly what you would expect:
{"Success":false}
As the above code illustrates I can correctly create an instance of my type using the new syntax but the Axios data property appears unaffected by the type declaration.
Just because something has the same properties as the class does not mean it is an instance of the class. In your case the response from the server is probably parsed using JSON.parse which will create simple objects. Only objects created using new GetSliceResponse will actually be instances of the class.
The type parameter to the post method is meant to help describe the shape of the response but will not actually change the runtime behavior (nor could it, genetics are erased during compilation).
This being said, you can still access the properties of the object as if the object was an instance of the class, the only thing that will not work is instanceof and don't expect any method to be present.
If you want to make sure nobody uses instanceof by mistake you can make the type am interface instead.
If you really need the class you can create an instance using new and use Object.assign to assign all fields
export class GetSliceResponse
{
Success: boolean;
}
Axios.post<GetSliceResponse>("myurl/Get", request).then(o => {
o = Object.assign(new GetSliceResponse(), o);
});

Qml property hooks

Suppose there is a Qml type called Test with foo property, it is implemented as follows:
Test.qml
// Not necessarily QtObject, but derived from QObject
QtObject {
// Not necessarily var/property, but must behave like property (i.e. be accessible using "<instance>.foo")
property var foo
}
And used in the following way:
main.qml
import "."
Test {
id: _test
}
function baz() {
var x = _test.foo;
_test.foo = x;
}
What I want is to be notified every time foo property is accessed by getter or setter. For setter perhaps I can use fooChanged signal, but there is no such solution for getter. Also I could implement Test type as a C++ class with Q_PROPERTY macro and emit corresponding signals form property getter/setter, but I would really like to leave most of the code on Qml side.
Is there any other way to hook Qml properties access?
Ok, after some hours of googling, reading Qml and JS documentation I think I have finally found a solution. It involves some hacks since JS is not fully supported in Qml, but this solution still works. The main idea is to use JS defineProperty method in order to add properties to existing objects dynamically. Now my Test.qml file looks like this:
QtObject {
// NOTE: .defineProperty does not correctly work for Qml objects, so JS object is used instead
property var object: { return {}; }
Component.onCompleted: {
Object.defineProperty(
object,
"foo",
{
get: function () {
// getter handling here
},
set: function (value) {
// setter handling here
}
}
);
}
}
And in main.qml _test instance is declared as follows:
property alias _test: _testDeclaration.object
Test {
id: _testDeclaration
}
Hope this answer will help other people.

JSHint with ECMAScript6: method is not defined

I'm implementing a client-side application using ECMAScript6 and use JSHint for static code analysis. I often use the following pattern in my code:
class MyClass {
constructor() {
//This is how I would like to call myMethod
myMethod();
//This is how I should call myMethod to make JSHint analysis pass
this.myMethod();
}
myMethod(){
//Implementation
}
}
My primary language is Java so I expect that simply calling myMethod() should be ok. However without adding this to method call I'm getting "'myMethod' is not defined" warning from JSHint. My questions are:
Is it correct to make calls without this in such situation? (e.g. in PHP you always need to add $this-> to non-static method call)
If that's correct to make calls without this is there any way (any .jshintrc flag) to turn off this warning in JSHint?
No, this is and never was correct in JavaScript. Methods always need to be called on a receiver explicitly to make this work, and they need to be referred to using property access notation because methods are just functions on properties in javascript. They're not available as functions in the scope of your other methods. It's the same for properties, btw.
JsHint is right here, and there's no reason to turn that warning off. Even if that may possible, executing your program in spite of that would just make it not work.
Is it correct to make calls without this in such situation? (e.g. in
PHP you always need to add $this-> to non-static method call)
No, it is not. You always have to specify the receiver of the method.
If that's correct to make calls without this is there any way (any
.jshintrc flag) to turn off this warning in JSHint?
JSHint returns "'myMethod' is not defined" warning correctly as there is not function called myMethod in the scope of the constructor.
In the code you provided the identifier myMethod isn't defined, but the inherited property myMethod of instances of MyClass is defined.
If you define myMethod as a Function under a closure which isn't available elsewhere then you can access as it in the form you desire
var MyClass = (function () {
function myMethod() {
//Implementation
}
class MyClass {
constructor() {
myMethod();
}
}
return MyClass;
}());
I don't get to write much ES6 so I'm not sure if putting the function myMethod inside MyClass's definition is a SyntaxError
Please note however that this is required to reference your specific instance of MyClass, so you'll probably need to use it somewhere if you want MyMethod to act on the instance.
function myMethod(obj) {...}
// ...
myMethod(this);
If you read the MDN's description of class
JavaScript classes are introduced in ECMAScript 6 and are syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax is not introducing a new object-oriented inheritance model to JavaScript. JS classes provide a much simpler and clearer syntax to create objects and dealing with inheritance.
This is saying using class is just shorthand for the old way of doing it, not a new model, so it may be easier to think of what your current code would look like if written in ES5,
var MyClass = (function () {
function MyClass() {
this.constructor.apply(this, arguments);
}
MyClass.prototype = Object.create(null);
MyClass.prototype.constructor = function () {
myMethod(); // referenceError
this.myMethod(); // works
};
MyClass.prototype.myMethod = function () {
//Implementation
};
return MyClass;
}());

dojo 1.9: what annotation does declare.safeMixin add?

I have been reading through the dojo 1.9 documentation about declare.safeMixin(), focusing on the difference between it and lang.mixin.
Here is the explanation I found...
safeMixin() is a function defined in dojo/declare. It has the same functionality as dojo/_base/lang::mixin(), but additionally it annotates all copied methods compatibly with dojo/declare. This decoration can affect how this.inherited() works in mixed-in methods.
I can follow the example but it doesn't really explain exactly what is added and where, can anyone give any further examples of what annotation is added to each copied method?
So to be clear, I'm not asking for an explanation of inheritance, I'm just asking specifically about the annotations added by using declare.safeMixin() instead of lang.mixin.
Using safeMixin allows you to mix functions into an instance that can take advantage of this.inherited the same way that prototype methods defined using declare can.
For example, the following will log 2 messages:
require([
"dojo/_base/lang",
"dojo/_base/declare"
], function(lang, declare){
var A = declare(null, {
method: function () {
console.log('method in prototype');
}
});
var a = new A();
declare.safeMixin(a, {
method: function () {
this.inherited(arguments);
console.log('method in instance');
}
});
a.method();
});
Without safeMixin, you wouldn't be able to call this.inherited(arguments) from the overriding method (at least, not without additional parameters) - you'd end up getting an error:
Error: declare: can't deduce a name to call inherited()
safeMixin adds the nom property to functions that are mixed in to the target. This property is set to the key from the source object that the function was assigned to. e.g. if you call declare.safeMixin(target, { foo: function() {} }), the nom property for that function is "foo". This is necessary for this.inherited(arguments) to automatically figure out that it should call the parent "foo". The alternative to using safeMixin would be to explicitly specify the name of the parent function: this.inherited('foo', arguments);.

Categories

Resources