Delete object behind parameter inside an function - javascript

Here an code example:
var testFunction = function(x) {
delete(x); //x = null
}
var array = ["test1", "test2", "test3"];
$.each(array, function(e, e1) {
testFunction(e1);
}
I'd like to delete an element out of the array inside an function. It would be possible to delete it with an index ( delete(array[1]) ) but I can't do this in my case because the delete function should be later inside an on-Button-Press function (one button per Array-Element) (not like in the example) and the index is dynamically changing.
The currently function would delete/set the x variable null and it won't affect the variable inside the array.
Is there a way to delete the referred object behind a variable? Maybe with .getObject() or something like this?
Edit:
Full example:
var createButton = function(object, placeThere) {
var oButton1 = new sap.ui.commons.Button({
text : ("Delete " + object.value),
});
//do some more not relevant stuff here
oButton1.attachPress(function() {
delete(object); /*deleteObjectOutOfArray*/
}
oButton1.placeAt(placeThere);
}
var array = [new Object(), new Object(), new Object()]; //array filled with objects with diffrent variables like for example value
$each (array, function(e1, e2) {
createButton(e2, "nameOfDiv");
}

// Declare array first, so following code can refer to it
var array = [new Object(), new Object(), new Object()];
var createButton = function(object, placeThere) {
// then after not relevant stuff:
oButton1.attachPress(function() {
array.splice(array.indexOf(object), 1); // this removes object from array
}
// rest of code
}

Related

".this" is not modifying the original object

I'm doing some practice with javascript data structures and am essentially trying to extend Array.
class Collection {
constructor(array){
let collection = Object.create(Array.prototype);
collection = (Array.apply(collection, array) || collection);
collection.clear = () => {
while(this.length > 0){
this.pop();
}
return this
};
return(collection);
}; }
The problem is that when I do the following
c = new Collection([1,2,3]);
c.clear();
c is still [1,2,3] when I am expecting [ ]. Why does modifying this not modify c?
Why does modifying this not modify c?
because this references an instance of Collection that you create with new Collection(...), while your constructor returns the value of let collection; which is NOT this in that context.
Besides that, your code is quite interresting. I think this is what you were trying to build:
class Collection extends Array {
constructor(array) {
// call the constructor of the Array class
super(array.length);
// copy the values from `array` onto `this`;
Object.assign(this, array);
}
clear() {
// that's all it takes to empty an Array
this.length = 0;
}
}
var c = new Collection([1, 2, 3]);
console.log(c);
c.clear();
console.log(c);
This is for the way you defining the function.
As you re defining as lamda expression, the value of this is not getting bound properly.
Change into to normal function declaration.
class Collection {
constructor(array){
let collection = Object.create(Array.prototype);
collection = (Array.apply(collection, array) || collection);
debugger;
collection.clear = function() {
while(this.length > 0){
this.pop();
}
return this
};
return(collection);
}; }
var c = new Collection([1,2,3]);
c.clear();
console.log(c);

Initialize array in javascript constructor

I have a constructor and i want to initialize an array inside the object to be created. This array is supposed to contain a couple of objects.
function Cluster3DObject(name){
this.name = name;
this.array = [];
}
Cluster3DObject.prototype.add = function(obj) {
this.array.push(this.obj);
};
Here i define the "class" and i have added one method "add" and it is supposed to push an object into this.array..
var cluster = new Cluster3DObject("clster");
var testObj = new THREE.CSS3DObject(testDiv);
var testVector = new THREE.Vector3();
cluster.add(testObj);
When i call the cluster.add method i get the "undefined is not a function error" but i can't seem to find out what i'm doing wrong?
i am new to using constructors..
It's not this.obj, just obj
Cluster3DObject.prototype.add = function(obj) {
this.array.push(obj);
};
otherwise it seems fine, but that wouldn't really produce a "undefined is not a function error", it would just push undefined, so the error probably comes from trying to use the array filled with undefined values ?
FIDDLE

Preserve function property when created with "bind"

I have a function that looks like this:
var tempFun = function() {
return 'something';
}
tempFun.priority = 100;
Now I'm pushing it to an array and binding another object to it in the process like this:
var funArray = [];
var newObj = {};
funArray.push( tempFun.bind(newObj) );
and after this, I would like to acces the function's property like this:
funArray[0].priority
but it returns undefined. Is there some way to preserve the property on the function while binding a new object to it?
No, but you could write a function to do this yourself;
Function.prototype.bindAndCopy = function () {
var ret = this.bind.apply(this, arguments);
for (var x in this) {
if (this.hasOwnProperty(x)) {
ret[x] = this[x];
}
}
return ret;
};
... which you could then use via;
var funArray = [];
var newObj = {};
funArray.push( tempFun.bindAndCopy(newObj) );
No. Bind returns a new function, which "wraps" around the original one. All you can do is copy the properties on this new function:
var boundFun = tempFun.bind(newObj)
boundFun.priority = tempFun.priority;
funArray.push( boundFun );
If you want the properties to be in sync (changes in one visible on the other) you can do:
Object.defineProperty(boundFun, 'priority', {
get : function () { return tempFun.priority; },
set : function (val) { tempFun.priority = val; }
});
From MDN:
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
Hence, .bind() won't be useful for what you're trying to achieve. Besides using jQuery mappers or rewriting your code to use .prototype, a solution that I can think of is:
var obj = {};
for (var i in tempFun) {
if (tempFun.hasOwnProperty(i)) obj[i] = tempFun[i];
}

Prototype chain - setting key on one object affects a sibling object?

I am working on my first JS project that involves inheritance and the prototype chain, and I am confused about why the creation of one object with specific data is affecting the data already in place on my second object.
The goal is to have a set of basic defaults in the full_params object literal in the "parent" object, and have some more specific defaults in the default_params object literal in the "child" object.
The child object specificRequest takes an array argument for its constructor function, adds those to its default_params, and then call the setOptions function of its prototype to add those to the full_params.
The problem is that when I create one specificRequest object and initialize it, it works fine, but then when I create a second specificRequest object, the full_params is already the same as
that of the first.
This is probably something very simple from a misunderstanding of how prototype works...
/////// PARENT OBJECT
function baseRequest(custom_params) {
var key;
this.full_params = {
"SignatureVersion": "2",
"Timestamp": Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'")
};
this.custom_params = custom_params;
}
baseRequest.prototype.setOptions = function(arg_options) {
var key;
if (typeof arg_options === "object") this.custom_params = arg_options;
// If an object of request options is passed, use that. Otherwise use whatever is already in the custom_params object.
for (key in this.custom_params) {
this.full_params[key] = this.custom_params[key];
}
}
///////// CHILD OBJECT
function specificRequest(mySKUList) {
var i;
this.mySKUList = mySKUList;
this.default_params = {
"Action": "myAction",
"Version": "2011-10-01"
};
for (i = 0; i < this.mySKUList.length; i++) {
var temp_sku = this.mySKUList[i];
var temp_sku_name = "SellerSKUList.SellerSKU." + (i + 1);
this.default_params[temp_sku_name] = temp_sku;
}
this.setOptions(this.default_params);
}
specificRequest.prototype = new baseRequest
///// Function to run
function testfoo() {
var skulist1 = ["AR6100", "AR6102", "WB1234"]
var skulist2 = ["XY9999"]
var req1 = new specificRequest(skulist1);
var req2 = new specificRequest(skulist2);
// Req1 has AR6100, AR6102, and WB1234 as parameters, as expected
// Req2 should only have XY9999, but instead has XY9999, AR6102, and WB1234
}
Well you have tied a concrete instance of the parent class to be the prototype of the child class with this line:
specificRequest.prototype = new baseRequest
Instead, don't instantiate the parent class at all:
specificRequest.prototype = Object.create( baseRequest.prototype );
Also, call super() equivalent when constructing a child instance:
function specificRequest(mySKUList) {
baseRequest.call( this );
...
}
And please start constructor names with UpperCase.

Returning an Javascript Object's property by Value NOT Reference

So I have a class foo that has a method which returns an array bar. I have another function that calls foo.getBar and then filters the array. I want to be able to always get the original contents of bar when I use a different filter, but bing seems to be just creating a reference to bar, not a separate array. I have tried using return this.bar.valueOf(); in my function foo, still not working. When I remove items from bing they are also removed from bar. Someone please enlighten me on creating a unique array instead of a reference.
function foo(x, y, z){
this.bar = new Array();
...
this.bar = [ some , stuff , in , bar ];
this.getBar = function getBar(){
return this.bar;
}
...
}
var FooObject = new foo(x,y,z);
function baz(){
var bing = FooObject.getBar();
bing.splice(remove some pieces of the array);
}
The easiest (and as far as I know, fastest) way to get a copy of an array is to use the slice method. Without any arguments, it defaults to array.slice(0, array.length), so it will copy the entire array.
Your getBar function would look like this:
this.getBar = function getBar(){
return this.bar.slice();
}
Note that this is a shallow copy, so any changes to the objects in the array will affect the original (adding and removing items won't affect it though).
For objects, use the clone method:
function cloneObject(source) {
for (i in source) {
if (typeof source[i] == 'source') {
this[i] = new cloneObject(source[i]);
}
else {
this[i] = source[i];
}
}
}
var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'};
var obj2= new cloneObject(obj1);
What you'll have to do is something like the following, passing a function as a parameter and force a pass-by-value;
function foo(x, y, z) {
this.bar = ['uno', 'dos', 'tres'];
}
foo.prototype.getBar = function() {
return this.bar;
}
...
function getBar(fn) {
return fn();
}
...
var f = new foo(x, y, z);
var bing = getBar(f.getBar);
Returning a "clone" will make sure original array is untouched. Note that such clone will be shallow.
function foo(x, y, z){
this.bar = [ some , stuff , in , bar ];
...
this.getBar = function getBar(){
return this.bar.concat([]);
}
...
}
Unfortunately javascript arrays and objects are always passed by reference. If you are guaranteed that your foo.bar array is 1-dimensional/contains no arrays or objects,
Then you can do:
var bing = FooObject.getBar().slice(0);
Which will do a 1-deep copy of foo.bar, resulting in your bing array being independent of the foo.bar array.
Otherwise you'll have to roll/find a deep copy method, such as the $A function in mootools
var newArray = $A(oldArray)

Categories