I have the following code to call an function on each button in a page.
dojo.query('.btn').forEach(function(item){
Obj = new MyClass(item); // class calls the ajax request on error of each btn click I have to handle some functionality in below function showError
dojo.connect(Obj, 'showError', dojo.hitch(Obj, function(errors){
console.log(Obj + 'came');
}));
Here I tried using dojo.hitch to maintain state of each object Obj, But it is not maintaining.Only first Obj is firing.For second Button also, the first Obj is firing.Is there anything I am missing here.
Obj is declared as a global variable. Try putting a var in front of it. For example:
var Obj = new MyClass(item);
If you don't provide the var, it will create a globally accessible variable called Obj. This means that each time you loop, you refer to the same global variable. The result of this is that each one is connected to the same Obj (and that's why both buttons are connected to the same object).
Also, read this question on StackOverflow to get a more detailed view about declaring variables and the global scope.
I am new to Javascript and now studying it...
var person = function() {
this.name = "name"
};
var person2 = function() {
var obj = {};
obj.name = "name";
return obj;
};
Let's suppose we have two functions shown above. It seems that objects can be created by using either of the functions. For example)
var p = new person();
var p2 = new person2();
My question is: What's difference between person vs person2? Are they exactly the same? If not which one is a more preferable way to use?
Thanks
The normal way of creating an object is the first way.
The second way will create two objects, and one will be discarded. One object will be created before the function is called, just as with the first method, but because the function returns another object the first object will be discarded and the returned object will be used instead.
An important difference between the methods is that the second one can't use a prototype. Anything that you put in the prototype of the function will be applied to the object that ends up being discarded.
The difference is in the way you use the functions.
The first one is intended to be used as a constructor, this being set to the newly created object. It is intended to be used in combination with the operator new, as follows:
var bill = new person();
This is just like a normal constructor as in typical OOP language.
The second one is intended to be used as a normal function (without new), e.g.:
var bill = person();
You can use this way of object creation in combination with the builder pattern.
I am trying to store function pointers of an object's functions in an array.But it's giving me problems when I want to access another property of the object within the function.Could any one solve this or give me an idea how to work around it?
function O(){
this.name="hello";
this.f=function(){
alert(this.name);//why does "this" refer to the array arr rather than the object?
};
this.arr=[];
this.arr["x"]=this.f;
}
var d=new O();
d.arr["x"]();
In this case, this will reference the object that the function was called as a method of (in your case, the array). You'll want to store a reference to the O function somewhere within the scope, such as:
function O(){
var self = this;
this.name="hello";
this.f=function(){
alert(self.name);//why does "this" refer to the array arr rather than the object?
};
this.arr=[];
this.arr["x"]=this.f;
}
var d=new O();
d.arr["x"]();
This is a pretty common pattern in JavaScript, and has the added benefit of allowing the function to execute the same way, whether it was called through d.f() or d.arr["X"]()
Basically i'm having trouble with something that i'm sure is super duper simple but I just don't know what to call it and therefore I am having trouble searching for an answer. :(
Basically, say I've declared an object, i.e var meow = {}; and then i decide to create an object within that by doing something like meow.cutekitten = {}; this is all straight forward and i end up with an object called cutekitten within that.
My issue is, what if I've declared cutekitten as a variable and i want to use the contents of that variable as the name of this new object rather than the variable name?
var propertyName = "cutekitten";
var meow = {};
meow[ propertyName ] = {};
I am writing a script in which I need to clone arrays in many different places. For this reason, I would like to do the following to emulate a cloning function:
var clone = [].slice.call;
var arr1 = [1,2,3,4,5,6,7,8,9,10];
var arr2 = clone(arr1, 0);
Unfortunately, the above code results in: TypeError: object is not a function. I realize there are many functions out there to do deep cloning and shallow copies but I just want to use the built in method. Interestingly enough, the following does work:
var clone = [].slice;
var arr1 = [1,2,3,4,5,6,7,8,9,10];
var arr2 = clone.call(arr1, 0);
Does anyone know why the first block doesn't work while the second does? Is there any way to reference a functions call and apply functions without throwing errors when calling the referenced function?
I have to definitely agree with both Felix King and pimvdb. I think the only drawback to using the Function.protoytpe.bind() function is the fact that this is not a function that is available in all browsers (IE6 for example). An alternative would be to use a JavaScript library that provides the curry() function. Another alternative would be to define a function which gives you the ability to retrieve the call function for any other function. Here is a definition that I posted on my blog for such a function which I called getCall():
Function.prototype.getCall = function() {
var realFn = this;
return function(objThis) {
return realFn.apply(objThis, Array.prototype.slice.call(arguments, 1));
};
};
Now, with this definition, you could do the following to get a reference to the call function of the slice function:
var slice = [].slice.getCall();
You can clone an array by calling slice directly:
var arr2 = arr1.slice();
If you want a clone function, you can do:
var clone = function(arr) { return arr.slice(); };
If you really want to prototype function (which is not necessary as long as the function is not overwritten):
var clone = function(arr) { return [].slice.call(arr); };
Why can't you reference call or apply directly?
It does not work for the same reason assigning a method of an object to a variable does not "work".
If you call func.call() then this inside call will be a reference to func, a function object.
If you assign call to a variable then the context is lost. You have a reference to the generic call function. Thus you'd have to pass the correct context (the method you want to apply call to) as first parameter to call again:
var clone = [].slice.call;
var arr2 = clone.call([].slice, arr1);
This is not really an improvement and quite confusing.
call and apply are methods that every functions inherits from Function.prototype. Functions don't have their own version of them. [].slice.call === [].splice.call yields true.
The difference is the scope of the function, i.e. what "this" is. I'm not sure what the correct technical terms are, but the "this" is not the same when a function is called "stand alone" or as a property of an object.
var myObj = {};
myObj.foo = function () {
console.log(this.bar);
};
myObj.bar = 1234;
var fooRef = myObj.foo;
myObj.foo(); // 1234
fooRef(); // undefined
You can however create a function that wraps a call to the function and passes on all the arguments:
var fooEncapsulated = function () {
return myObj.foo.apply(myObj, arguments);
}
fooEncapsulated(); // 1234
For the record, the most common way of doing this is:
Array.prototype.slice.call(myArray, other, arguments, here);
The problem is that whatever_function.call is equal to Function.prototype.call. Thus, you effectively save a reference to Function.prototype.call and the information that it is the slice function is lost.
Compare it with a custom function:
Function.prototype.custom = function() { console.log(this) };
[].slice.custom(); // logs slice function
var ref = [].slice.custom;
ref(); // logs window object
A method of keeping the this value from being changed is using Function.prototype.bind:
var ref = [].slice.call.bind([].slice);
Now,
ref([1,2,3], 1); // [2, 3]
because when calling the .call function, the this value is bound to the slice function and everything works as expected.
Sweet and simple:
slice = Function.prototype.call.bind(Array.prototype.slice);
slice([1,2,3]); // [1,2,3]
slice({length:3,0:1,1:2,2:3}); // [1,2,3]