I have been instructed to make a Maths.js which will have Vector properties such as adding, multiplication, dot product and cross product. Calculating these is fine, but i am new to javascript and i would like a few ideas on how to go about this. Can i make a Vector.js with 3 vars: val1, val2, val3 and pass them through a constructor to another javascript file called Maths.js ? Then in Maths.js do my mathematics ? Then of course in my HTML file make a few buttons once the user enters a value. I have been googling about constructors and getters and setters in javascript and have found this is achievable. Thanks for the help in advance.
This is what i have tried
Vector.js
<script>
var value1 = 0;
var value2 = 0;
var value3 = 0;
function Vector (var val1, var val2, var val3)
{
this.value1 = val1;
this.value2 = val2;
this.value3 = val3;
}
function getValue1()
{
return this.value1;
}
function setValue2(val)
{
this.value1 = val;
}
function getValue2()
{
return this.value2;
}
function setValue2(val)
{
this.value2 = val;
}
function getValue3()
{
return this.value3;
}
function setValue3(val)
{
this.value3 = val;
}
</script>
You can do this in just one file Math.js:
function Vector(x,y,z) {
var self = this;
self.x = x;
self.y = y;
self.z = z;
self.add = function(v) {
return new Vector(self.x+v.x,self.y+v.y,self.z+v.z); }
self.minus = function(v) { /*TODO*/ }
self.dot = function(v) { /*TODO*/ }
self.cross = function(v) { /*TODO*/ }
}
In your main html file:
var v1 = new Vector(1,2,3);
var v2 = new Vector(4,5,6);
var v3 = v1.add(v2);
...
Related
Let's say i have this code:
var m =
{
init: function(num, num2, num3)
{
this.num = num;
this.num2 = num2;
this.num3 = num3;
}
};
var t =
{
create: function()
{
var obj = Object.create(m);
obj.init(1,2,3);
}
};
t.create();
console.log(obj)
When executing this code i get this error:
obj is not defined
How can I make obj work outside the method create ?
Change your create function to return the obj.
Then, you can do var obj = t.create().
Here is the complete code:
var m =
{
init: function(num, num2, num3)
{
this.num = num;
this.num2 = num2;
this.num3 = num3;
}
};
var t =
{
create: function()
{
var obj = Object.create(m);
obj.init(1,2,3);
return obj;
}
};
var obj = t.create();
console.log(obj)
obj is a local variable to the function create. You need to return it to provide access to it outside of that function.
var t =
{
create: function()
{
var obj = Object.create(m);
obj.init(1,2,3);
return obj;
}
};
var obj = t.create();
console.log(obj)
Returning the object created would solve your issue. The obj is a local variable bound to the scope of the create function you cannot access it outside.
var m =
{
init: function(num, num2, num3)
{
this.num = num;
this.num2 = num2;
this.num3 = num3;
}
};
var t =
{
create: function()
{
var obj = Object.create(m);
obj.init(1,2,3);
return obj;
}
};
let obj = t.create();
console.log(obj);
I am very much new to Javascript
please correct my code or suggest the best option
var myApp = {};
myApp.set = function(VAL) {
myApp.id = VAL;
}
myApp.get = function() {
return myApp.id;
}
function PageLoad() {
var X = new myApp;
var Y = new myApp;
Y.set(20);
X.set(10);
alert(X.get());
alert(Y.get());
}
It shows last assign value only i.e. 10 :(
Thanks in Advance
Manoj
#Manoj Chavanke Sir Please use this code
function myApp(){
}
myApp.prototype.set = function(VAL) {
this.id = VAL;
}
myApp.prototype.get = function() {
return this.id;
}
function PageLoad() {
var X = new myApp; console.log(X);
var Y = new myApp; console.log(Y);
Y.set(20);
X.set(10);
alert(X.get());
alert(Y.get());
}
PageLoad();
I think You override the value myApp.id = VAL;
try this code
var myApp = [];
myApp.set = function(VAL) {
myApp.push({id : VAL});
}
instate of
var myApp = {};
myApp.set = function(VAL) {
myApp.id = VAL;
}
Because the key is a unique you can't use twice.
I have a sealed object with an array member on which I want to prevent direct pushes.
var myModule = (function () {
"use strict";
var a = (function () {
var _b = {},
_c = _c = "",
_d = [];
Object.defineProperty(_b, "c", {
get: function () { return _c; }
});
Object.defineProperty(_b, "d", {
get { return _d; }
});
_b.addD = function (newD) {
_d.push(newD);
};
Object.seal(_b);
return _b;
}());
var _something = { B: _b };
return {
Something: _something,
AddD: _b.addD
};
}());
myModule.Something.c = "blah"; // doesn't update = WIN!!
myModule.AddD({}); // pushed = WIN!
myModule.Something.d.push({}); // pushed = sadness
How can I prevent the push?
UPDATE:
Thanks for all the thoughts. I eventually need the JSON to send to the server. It looks like I might need to use an object for the array then figure out a way to generate and return the JSON needed, or change _something to use .slice(). Will play and report.
you could override the push method:
var _d = [];
_d.__proto__.push = function() { return this.length; }
and when you need to use it in your module, call Array.prototype.push:
_b.addD = function (newD) {
Array.prototype.push.call(_d, newD);
};
I haven't done any performance tests on this, but this certainly helps to protect your array.
(function(undefined) {
var protectedArrays = [];
protectArray = function protectArray(arr) {
protectedArrays.push(arr);
return getPrivateUpdater(arr);
}
var isProtected = function(arr) {
return protectedArrays.indexOf(arr)>-1;
}
var getPrivateUpdater = function(arr) {
var ret = {};
Object.keys(funcBackups).forEach(function(funcName) {
ret[funcName] = funcBackups[funcName].bind(arr);
});
return ret;
}
var returnsNewArray = ['Array.prototype.splice'];
var returnsOriginalArray = ['Array.prototype.fill','Array.prototype.reverse','Array.prototype.copyWithin','Array.prototype.sort'];
var returnsLength = ['Array.prototype.push','Array.prototype.unshift'];
var returnsValue = ['Array.prototype.shift','Array.prototype.pop'];
var funcBackups = {};
overwriteFuncs(returnsNewArray, function() { return []; });
overwriteFuncs(returnsOriginalArray, function() { return this; });
overwriteFuncs(returnsLength, function() { return this.length; });
overwriteFuncs(returnsValue, function() { return undefined; });
function overwriteFuncs(funcs, ret) {
for(var i=0,c=funcs.length;i<c;i++)
{
var func = funcs[i];
var funcParts = func.split('.');
var obj = window;
for(var j=0,l=funcParts.length;j<l;j++)
{
(function() {
var part = funcParts[j];
if(j!=l-1) obj = obj[part];
else if(typeof obj[part] === "function")
{
var funcBk = obj[part];
funcBackups[funcBk.name] = funcBk;
obj[part] = renameFunction(funcBk.name, function() {
if(isProtected(this)) return ret.apply(this, arguments);
else return funcBk.apply(this,arguments);
});
}
})();
}
}
}
function renameFunction(name, fn) {
return (new Function("return function (call) { return function " + name +
" () { return call(this, arguments) }; };")())(Function.apply.bind(fn));
};
})();
You would use it like so:
var myArr = [];
var myArrInterface = protectArray(myArr);
myArr.push(5); //Doesn't work, but returns length as expected
myArrInterface.push(5); //Works as normal
This way, you can internally keep a copy of the interface that isn't made global to allow your helper funcs to modify the array as normal, but any attempt to use .push .splice etc will fail, either directly, or using the .bind(myArr,arg) method.
It's still not completely watertight, but a pretty good protector. You could potentially use the Object.defineProperty method to generate protected properties for the first 900 indexes, but I'm not sure of the implications of this. There is also the method Object.preventExtensions() but I'm unaware of a way to undo this effect when you need to change it yourself
Thank you, dandavis!
I used the slice method:
var myModule = (function () {
"use strict";
var a = (function () {
var _b = {},
_c = _c = "",
_d = [];
Object.defineProperty(_b, "c", {
get: function () { return _c; }
});
Object.defineProperty(_b, "d", {
get { return _d.slice(); } // UPDATED
});
_b.updateC = function (newValue) {
_c = newValue;
};
_b.addD = function (newD) {
_d.push(newD);
};
Object.seal(_b);
return _b;
}());
var _something = { B: _b };
return {
Something: _something,
AddD: _b.addD
};
}());
myModule.Something.c = "blah"; // doesn't update = WIN!!
myModule.AddD({}); // pushed = WIN!
myModule.Something.d.push({}); // no more update = happiness
This allows me to protect from direct push calls enforcing some logic.
I have created a Util API's to create function object and to invoke its function API's
function FunctionUtils() {
}
FunctionUtils.createFunctionInstance = function(functionName) {
var obj = FunctionUtils.createFunctionInstanceDescend(window, functionName);
return new obj();
}
FunctionUtils.createFunctionInstanceDescend = function(obj, path) {
var parts = path.split('.');
for(var i = 0; i < parts.length; i++) {
obj = obj[parts[i]];
}
return obj;
}
FunctionUtils.invokeAndInflate = function(object, functionName, parameterValue) {
object[functionName](parameterValue);
}
This Util API's work for below code:
function Student() {
var firstName;
var city, country;
this.getFirstName = function() {
return firstName;
}
this.setFirstName = function(val) {
firstName = val;
}
this.getAddress() {
return city + country;
}
this.setAddress(val1, val2) {
city = val1;
country = val2;
}
}
var student = FunctionUtils.createFunctionInstance("Student");
FunctionUtils.invokeAndinflate(student, "setFirstName", "Pranav"); //Works
FunctionUtils.invokeAndInflate(student, "setAddress", "LA", "USA"); //Doesn't Work.
How to use FunctionUtils.invokeAndInflate API for more than one parameters ? ?
You can rewrite the FunctionUtils.invokeAndInflate function as below:
FunctionUtils.invokeAndInflate = function(object, functionName, parameterValue) {
object[functionName].apply(object, Array.prototype.slice.call(arguments, 2));
}
I suggest you reading about .call() and .apply(), here is an article about them.
http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx
I've made some new objects with object methods and I'm having trouble returning the information.
I intend for allPages to be a 2d array:
var allPages = [[]];
function textbox(type)
{
this.type=type;
this.getInfo = function () { return ( this.type ); };
}
function addTextbox(dropdown)
{
var myindex = dropdown.selectedIndex;
var SelValue = dropdown.options[myindex].value;
if(SelValue == "String")
{
var tb = new textbox("string");
allPages[allPages.length-1].push(tb);
var string = "";
for (i = 0;i < allPages.length;i++)
{
for(j = 0;j < allPages[i].length;j++)
{
string = string + allPages[i][j].getInfo;
}
}
<!-- Problem here: prints "function () { return this.type; }"-->
document.write(string);
}
}
}
You are not calling the function, you are referencing it
allPages[i][j].getInfo;
should be
allPages[i][j].getInfo();
3 lines above where you state the problems exists, it should be:
string = string + allPages[i][j].getInfo(); // mind the () at the end.