Related
Here is a simple function, that counts the price of engraving, based on the entered phrase length.
function engravePrice(phraseToEngrave) {
var pricePerWord = 11;
var wordsToEngrave = phraseToEngrave.split(' ');
if (phraseToEngrave.length === 0){
return 0;
} else if (phraseToEngrave.length > 0){
return wordsToEngrave.length * pricePerWord;
}
}
console.log(`Gift wrap and engraving price is: ${engravePrice('')} Q`);
It actually works pretty well:
engravePrice('Two words') //will return 22, as expected
engravePrice('') //will return 0, as expected
except for one specific situation:
engravePrice() //when it breaks, saying "cannot read property 'split' of undefined"
Is there a solution for that?
Thanks.
You need to check phraseToEngrave.for undefined, e.g.
function engravePrice(phraseToEngrave) {
if (!phraseToEngrave) return 0;
...
}
or in ES6, give it a default:
function engravePrice(phraseToEngrave = '') {
...
}
I would do it like this:
function engravePrice(phraseToEngrave) {
var phraseToEngrave = phraseToEngrave || '';
var pricePerWord = 11;
var wordsToEngrave = phraseToEngrave.split(' ');
if (phraseToEngrave.length === 0){
return 0;
} else if (phraseToEngrave.length > 0){
return wordsToEngrave.length * pricePerWord;
}
}
Which just converts it to an empty string if nothing is passed.
Suppose I have following piece of code that contains an infinite loop:
function infiniteLoop() {
while(true) {
//do something, eg.
document.getElementById("someID").innerHTML = "Blah";
}
}
If we execute this code in an online compiler, browser will crash. I want to prevent that from happening. So I tried following code following this answer:
function willNotCrash() {
myVar = setInterval(infiniteLoop, 5000);
setTimeout(function(){
clearInterval(myVar);
}, 4000);
}
This code doesn't make the browser to crash, because I am stopping the execution before infiniteLoop() gets called by clearInterval(myVar).
My question is how do I stop executing such functions if they don't response within some period of time (eg. after 5 seconds or before the browser is crashed).
For example, if we copy paste following java code in https://www.compilejava.net/
public class HelloWorld {
public static void main(String[] args) {
while(true) {
System.out.println("Blah");
}
}
}
we get a nice output saying,
Script was taking longer than 5 seconds to execute so it was killed.
Here is my current code: http://js.do/code/106546
This is a bit tricky but perfectly doable. You need to tokenize the script and then rebuild it but insert a counter increment in every loop and function call. If the counter goes above some threshold, then bomb out. I did it here: https://littleminigames.com/
You can see the source at https://bitbucket.org/cskilbeck/littleminigames/src
The interesting bits are in wrapper.js (https://bitbucket.org/cskilbeck/littleminigames/src/ac29d0d0787abe93c75b88520050a6792c04d34d/public_html/static/js/wrapper.js?at=master&fileviewer=file-view-default)
Google escodegen, estraverse and esprima
I relied heavily on this: https://github.com/CodeCosmos/codecosmos/blob/master/www/js/sandbox.js
wrapper.js, as requested:
// Don't obfuscate this file! We depend on the toString() of functions!
// this was all nicked from https://github.com/CodeCosmos/codecosmos/blob/master/www/js/sandbox.js
(function(mainApp) {
'use strict';
var esprima = window.esprima,
estraverse = window.estraverse,
escodegen = window.escodegen,
errors = [],
eng,
Syntax = estraverse.Syntax;
// This implements the jankiest possible "source map", where we keep an array
// of [generatedLine, knownSourceLine]. Seems to essentially work.
function SourceNode(line, col, _sourceMap, generated) {
this.line = line;
this.col = col;
this.generated = generated;
}
SourceNode.prototype.toStringWithSourceMap = function toStringWithSourceMap() {
var code = [];
var mapLines = {};
var map = [];
// assumes that wrapCode adds two lines
var line = 3;
var lastMapLine = null;
function walk(node) {
if (typeof(node) === "string") {
if (node) {
code.push(node);
var matches = node.match(/\n/g);
if (matches !== null) {
line += matches.length;
}
}
} else if (node instanceof SourceNode) {
if (node.line !== null) {
if (!mapLines[line]) {
map.push([line, node.line]);
mapLines[line] = node.line;
}
}
walk(node.generated);
} else {
node.forEach(walk);
}
}
walk(this);
return {
code: code.join(''),
map: map
};
};
SourceNode.prototype.toString = function toString() {
return this.toStringWithSourceMap().code;
};
// This is used by escodegen
window.sourceMap = {
SourceNode: SourceNode
};
// TODO (chs): add in all the things that need to be masked
function runWrapper($userCode, __sys) {
var clear = __sys.clear,
setpixel = __sys.setpixel,
rectangle = __sys.rectangle,
box = __sys.box,
line = __sys.line,
getpixel = __sys.getpixel,
getpixeli = __sys.getpixeli,
keypress = __sys.keypress,
keyrelease = __sys.keyrelease,
keyheld = __sys.keyheld,
reset = __sys.reset;
__sys.userFunction = __sys.catchErrors($userCode);
}
function extractCode(fn) {
var code = fn.toString();
return code.substring(code.indexOf('{') + 1, code.lastIndexOf('}'));
}
function makeOneLine(code) {
return code.replace(/(\/\/[^\n]+|\n\s|\r\n\s*)/g, '');
}
var runTemplate = makeOneLine(extractCode(runWrapper));
function wrapCode(code, template, functionName, postCode) {
// avoid interpretation of the replacement string by using a fun.
// otherwise mo' $ mo problems.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter
return ("'use strict';" + template.replace(/\$userCode/, function() {
return 'function ' + functionName + '() {\n' + code + postCode + '\n}';
}));
}
var injectStatement = esprima.parse("if (++__sys.ctr >= __sys.maxctr) throw new Error('Script halted - infinite loop?');").body[0];
var injectElseStatement = esprima.parse("if (++__sys.ctr >= __sys.maxctr) throw new Error('Script halted - infinite loop?'); else ;").body[0];
function CallExpression(callee, args) {
this.callee = callee;
this.arguments = args;
}
CallExpression.prototype.type = Syntax.CallExpression;
function Identifier(name) {
this.name = name;
}
Identifier.prototype.type = Syntax.Identifier;
function BlockStatement(body) {
this.body = body;
}
BlockStatement.prototype.type = Syntax.BlockStatement;
function ReturnStatement(argument) {
this.argument = argument;
}
ReturnStatement.prototype.type = Syntax.ReturnStatement;
function FunctionExpression(id, params, body) {
this.id = id;
this.params = params;
this.body = body;
this.defaults = [];
this.expression = false;
this.generator = false;
this.rest = null;
}
FunctionExpression.prototype.type = Syntax.FunctionExpression;
function wrapId(node, defaultName) {
if (node.loc) {
var id = (node.id || {
name: null,
loc: null
});
var loc = id.loc || node.loc;
var name = id.name || defaultName;
return new Identifier(name + '$' + loc.start.line);
} else {
return node.id;
}
}
function instrumentAST(ast) {
var identifierStack = [];
function pushIdentifier(s) {
identifierStack[identifierStack.length - 1].push(s);
}
function popIdentifierStack() {
identifierStack.pop();
}
function pushIdentifierStack() {
identifierStack.push([]);
}
function peekLastIdentifier() {
var lastStackIdx = identifierStack.length - 1;
if (lastStackIdx >= 0) {
var stack = identifierStack[lastStackIdx];
if (stack.length) {
return stack[stack.length - 1];
}
}
return '';
}
pushIdentifierStack();
return estraverse.replace(ast, {
enter: function enterAST(node) {
switch (node.type) {
case Syntax.VariableDeclarator:
if (node.id.type === Syntax.Identifier) {
pushIdentifier(node.id.name);
}
break;
case Syntax.MemberExpression:
if (node.object.type === Syntax.Identifier) {
var id = node.object.name;
if (node.property.type === Syntax.Identifier) {
id += '__dot__' + node.property.name; // huh? why mangle these?
// console.log(id);
}
pushIdentifier(id);
} else if (node.property.type === Syntax.Identifier) {
pushIdentifier(node.property.name);
}
break;
case Syntax.FunctionDeclaration:
pushIdentifierStack();
break;
case Syntax.FunctionExpression:
pushIdentifierStack();
break;
default:
break;
}
return node;
},
leave: function leaveAST(node) {
switch (node.type) {
case Syntax.DoWhileStatement:
break;
case Syntax.ForStatement:
break;
case Syntax.FunctionDeclaration:
break;
case Syntax.FunctionExpression:
break;
case Syntax.WhileStatement:
break;
default:
return estraverse.SKIP;
}
// modify the BlockStatement in-place to inject the instruction counter
if(node.body.body === undefined) {
// they have used a non-block statement as the body of a function or loop construct
// not allowed for function declarations - should never get here
if(node.type === Syntax.FunctionDeclaration) {
errors.push({
message: "Missing {",
line: node.loc.start.line,
column: node.loc.start.column
});
}
else {
// otherwise insert the test
var newBody = angular.copy(injectElseStatement);
newBody.alternate = node.body;
node.body = newBody;
}
return estraverse.SKIP;
}
node.body.body.unshift(injectStatement);
if (node.type === Syntax.FunctionExpression) {
popIdentifierStack();
// __catchErrors(node)
node.id = wrapId(node, peekLastIdentifier());
return new CallExpression(
new Identifier("__sys.catchErrors"), [node]);
}
if (node.type === Syntax.FunctionDeclaration) {
popIdentifierStack();
// modify the BlockStatement in-place to be
// return __catchErrors(function id() { body });
var funBody = node.body;
node.body = new BlockStatement([
new ReturnStatement(
new CallExpression(
new CallExpression(
new Identifier("__sys.catchErrors"), [new FunctionExpression(
wrapId(node, peekLastIdentifier()), [],
funBody)]), []))
]);
}
return node;
}
});
}
// mainApp.sandbox('var a = 1; function update(frame) { clear(0); }').code
// give it the source code as a string
mainApp.sandbox = function(code) {
var rc = {};
this.errors = [];
try {
this.ast = instrumentAST(esprima.parse(code, { range: true, loc: true }));
this.map = escodegen.generate(this.ast, { sourceMap: true, sourceMapWithCode: true });
this.code = wrapCode(this.map.code, runTemplate, '', ';\n__sys.updateFunction = (typeof update === "function") ? update : null;');
}
catch(e) {
this.errors.push({
message: e.description,
line: e.lineNumber,
column: e.column
});
}
if(this.code) {
this.code = "eng.clientFunction = function(__sys) {" + this.code + "};";
}
};
mainApp.sandbox.prototype.searchMap = function(needle) {
// binary search
var lo = 0;
var hi = this.map.map.length;
var mid, here;
while (true) {
mid = lo + ((hi - lo) >> 1);
here = this.map.map[mid];
if (mid === lo || here[0] === needle) {
return here[1];
} else if (here[0] > needle) {
hi = mid;
} else {
lo = mid;
}
}
};
})(mainApp);
Typically all JavaScript runs in one thread, so it is impossible to run any JavaScript that could stop your loop while your loop is running. Using HTML5 web workers, you can run the infinite loop in a separate thread, and then you can terminate it:
var myWorker = new Worker( '/infinite.js ');
setTimeout( function ( ) {
myWorker.terminate( );
}, 5000 );
However your web worker won't have access to the DOM, so the contents of your infinite loop would need to be different that what you have in your question.
I found exactly what I was looking for in Bergi's comment,
Alternatively, place a if (Date.now() > dateAtStartOfExecution+5000) return; in every loop body.
So now my code looks like:
function infiniteLoop() {
dateAtStartOfExecution = Date.now();
while(true) {
//do something
document.getElementById("someID").innerHTML = "Blah";
if (Date.now() > dateAtStartOfExecution+5000) {
alert("Taking too much time. Killing.");
return;
}
}
}
If I run this code after 5 seconds I will get an alert and the execution will stop. Try this:
http://js.do/code/106565
I have the following javascript function to open and close sub list elements on an onclick event:
function ShowHideDtls(itId) {
var subMen = document.getElementById(itId);
if (subMen != null) {
if (subMen.className == "nav nav-second-level collapse in") {
subMen.className = "nav nav-second-level collapse";
} else {
subMen.className += " in";
}
}
}
The "collapse" is a css class which makes display=none hiding the sub list and "in" is a class which makes display=block showing the sub list, creating a menu with submenus.
I found in this question Change an element's class with JavaScript in the first(accepted) answer use of a regex in order to do this. I tried it like this:
function ShowHideDtls(itId) {
var subMen = document.getElementById(itId);
if (subMen != null) {
if (subMen.className.match(/(?:^|\s)in(?!\S)/)) {
subMen.className.replace(/(?:^|\s)in(?!\S)/g, '');
} else {
subMen.className += " in";
}
}
}
The code without the regex works perfectly but with the regex it doesn't. I checked the regex in regex101.com and it seems to work there. As I understand it's more appropriate to use the regex than a long string of all the class names and also I also have a nav-third-level class that I have to close and open so the regex seems to be the convenient and proper way to do it.
What's wrong?
Thank you.
No need of regex here. You can use classList
Using classList is a convenient alternative to accessing an element's list of classes as a space-delimited string via element.className.
function ShowHideDtls(itId) {
var subMen = document.getElementById(itId);
if (subMen != null) {
subMen.classList.toggle('in');
}
}
toggle() will toggle the class of the element. If the element already has the class, it'll remove it, if not then toggle will add the class to the element.
Check the Browser Compatibility.
You can use following SHIM from MDN for IE9,
/*
* classList.js: Cross-browser full element.classList implementation.
* 2014-07-23
*
* By Eli Grey, http://eligrey.com
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
/*global self, document, DOMException */
/*! #source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
if ("document" in self) {
// Full polyfill for browsers with no classList support
if (!("classList" in document.createElement("_"))) {
(function (view) {
"use strict";
if (!('Element' in view)) return;
var
classListProp = "classList",
protoProp = "prototype",
elemCtrProto = view.Element[protoProp],
objCtr = Object,
strTrim = String[protoProp].trim || function () {
return this.replace(/^\s+|\s+$/g, "");
},
arrIndexOf = Array[protoProp].indexOf || function (item) {
var
i = 0,
len = this.length;
for (; i < len; i++) {
if (i in this && this[i] === item) {
return i;
}
}
return -1;
}
// Vendors: please allow content code to instantiate DOMExceptions
,
DOMEx = function (type, message) {
this.name = type;
this.code = DOMException[type];
this.message = message;
},
checkTokenAndGetIndex = function (classList, token) {
if (token === "") {
throw new DOMEx(
"SYNTAX_ERR", "An invalid or illegal string was specified"
);
}
if (/\s/.test(token)) {
throw new DOMEx(
"INVALID_CHARACTER_ERR", "String contains an invalid character"
);
}
return arrIndexOf.call(classList, token);
},
ClassList = function (elem) {
var
trimmedClasses = strTrim.call(elem.getAttribute("class") || ""),
classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [],
i = 0,
len = classes.length;
for (; i < len; i++) {
this.push(classes[i]);
}
this._updateClassName = function () {
elem.setAttribute("class", this.toString());
};
},
classListProto = ClassList[protoProp] = [],
classListGetter = function () {
return new ClassList(this);
};
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function (i) {
return this[i] || null;
};
classListProto.contains = function (token) {
token += "";
return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function () {
var
tokens = arguments,
i = 0,
l = tokens.length,
token, updated = false;
do {
token = tokens[i] + "";
if (checkTokenAndGetIndex(this, token) === -1) {
this.push(token);
updated = true;
}
}
while (++i < l);
if (updated) {
this._updateClassName();
}
};
classListProto.remove = function () {
var
tokens = arguments,
i = 0,
l = tokens.length,
token, updated = false,
index;
do {
token = tokens[i] + "";
index = checkTokenAndGetIndex(this, token);
while (index !== -1) {
this.splice(index, 1);
updated = true;
index = checkTokenAndGetIndex(this, token);
}
}
while (++i < l);
if (updated) {
this._updateClassName();
}
};
classListProto.toggle = function (token, force) {
token += "";
var
result = this.contains(token),
method = result ?
force !== true && "remove" :
force !== false && "add";
if (method) {
this[method](token);
}
if (force === true || force === false) {
return force;
} else {
return !result;
}
};
classListProto.toString = function () {
return this.join(" ");
};
if (objCtr.defineProperty) {
var classListPropDesc = {
get: classListGetter,
enumerable: true,
configurable: true
};
try {
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
} catch (ex) { // IE 8 doesn't support enumerable:true
if (ex.number === -0x7FF5EC54) {
classListPropDesc.enumerable = false;
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
}
}
} else if (objCtr[protoProp].__defineGetter__) {
elemCtrProto.__defineGetter__(classListProp, classListGetter);
}
}(self));
} else {
// There is full or partial native classList support, so just check if we need
// to normalize the add/remove and toggle APIs.
(function () {
"use strict";
var testElement = document.createElement("_");
testElement.classList.add("c1", "c2");
// Polyfill for IE 10/11 and Firefox <26, where classList.add and
// classList.remove exist but support only one argument at a time.
if (!testElement.classList.contains("c2")) {
var createMethod = function (method) {
var original = DOMTokenList.prototype[method];
DOMTokenList.prototype[method] = function (token) {
var i, len = arguments.length;
for (i = 0; i < len; i++) {
token = arguments[i];
original.call(this, token);
}
};
};
createMethod('add');
createMethod('remove');
}
testElement.classList.toggle("c3", false);
// Polyfill for IE 10 and Firefox <24, where classList.toggle does not
// support the second argument.
if (testElement.classList.contains("c3")) {
var _toggle = DOMTokenList.prototype.toggle;
DOMTokenList.prototype.toggle = function (token, force) {
if (1 in arguments && !this.contains(token) === !force) {
return force;
} else {
return _toggle.call(this, token);
}
};
}
testElement = null;
}());
}
}
If you're using jQuery, you can use toggleClass():
function ShowHideDtls(itId) {
$('#' + itId).toggleClass('in');
}
Edit
If you still want to use regex:
if (/\bin\b/.test(subMen.className))
subMen.className.replace(/\bin\b/, '');
} else {
subMen.className += " in";
}
You can also use split() and indexOf as follow to check if a class is present on element.
var classes = className.split(/\s+/),
classIndex = classes.indexOf('in');
if (classIndex > -1) {
classes.splice(classIndex, 1);
subMen.className = classes.join(' ');
} else {
subMen.className += " in";
}
replace function returns the resultant value, it do not assign value indirectly.
So do following:
function ShowHideDtls(itId) {
var subMen = document.getElementById(itId);
if (subMen != null) {
if (subMen.className.match(/(?:^|\s)in(?!\S)/)) {
subMen.className = subMen.className.replace(/(?:^|\s)in(?!\S)/g, '');
}
else {
subMen.className += " in";
}
}
}
I have been working on a project that allows the user to submit memories about a place they have visited and tracks the location of when the memory was submitted. My only problem is trying to use localStorage with the app, I read about the JSON.stringify and JSON.parse, and don't understand how to use them in my code yet.
This is my form.js
It processes the form and grabs the text fields. It clears the form when the add button(on the display details page) or the enter details button is clicked. Finally it receives the information and sends out the message back to the window.
function processForm(){
var locate = document.myform.locate.value;
var details = document.myform.details.value;
var storeData = [];
localStorage.setItem("locate", JSON.stringify(locate));
localStorage.setItem("details", JSON.stringify(details));
alert("Saved: " + localStorage.getItem("locate") + ", and " + localStorage.getItem("details"));
var date = new Date,
day = date.getDate(),
month = date.getMonth() + 1,
year = date.getFullYear(),
hour = date.getHours(),
minute = date.getMinutes(),
ampm = hour > 12 ? "PM" : "AM";
hour = hour % 12;
hour = hour ? hour : 12; // zero = 12
minute = minute > 9 ? minute : "0" + minute;
hour = hour > 9 ? hour : "0" + hour;
date = month + "/" + day + "/" + year + " " + hour + ":" + minute + " " + ampm;
localStorage.setItem("date", JSON.stringify(date));
storeData.push(locate, details, date);
localStorage.setItem("storeData", JSON.stringify(storeData));
}
function clearForm(){
$('#myform').get(0).reset();
}
function retrieveFormInfo(){
var data = JSON.parse(localStorage.getItem("storeData"));
var locate = JSON.parse(localStorage.getItem("locate"));
$("#locate2").html("Place: " + locate);
var details = JSON.parse(localStorage.getItem("details"));
$("#details2").html("Description: " + details);
var date = JSON.parse(localStorage.getItem("date"));
$("#date").html(date);
}
But the major problem I am running into is I do know how to take that information in correctly using the JSON.stringify and JSON.parse and appending it to the window with html elements dynamically, Mainly like a list of memories.
Any help is appreciated!
localStorage stores key value pairs as strings only (you can use integer for keys but they get converted to string automatically).
Storage objects are simple key-value stores, similar to objects, but they stay intact through page loads. The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings) reference
let's say you have an array to be stored with each item being a json object.
You got 2 options:
Option 1:
stringify every item and store in locaStorage
var item = {input1: 'input1value', input2: 'input2value' };
localStorage.setItem( itemIndex, JSON.stringify(item) );
to retrive the items iterate over localStorage items and then convert the item to JSON object:
for(var i=0;i<localStorage.length; i++) {
var key = localStorage.key( i );
var item = JSON.parse( localStorage.getItem( key ) );
}
Option 2:
stringify the entire array and store in localStorage
localStorage.setItem( 'memoriesdata', JSON.stringify( arr ) );
to read the data read the item as string then convert to JSON object
var arr = JSON.parse( localStorage.getItem('memoriesdata') );
First get values of your input fields into a javascript object.
var myMemory = {};
myMemory.location = document.getElementById('location').value;
myMemory.description = document.getElementById('description').value;
Now save myMemory to localStorage,this can be done on a form submission or a button press. We can store as an array of memories and add item to it every time.
//if user already has memories in local, get that array and push into it.
//else create a blank array and add the memory.
memories = localStorage.getItem('memories') ?
JSON.parse(localStorage.getItem('memories')) :
[];
memories.push(myMemory);
localStorage.setItem('memories', JSON.stringify(memories));
I use this Storage implementation. It's inspired by many storage plugins out there... It handles any value serilizable by JSON.stringify function, and should work xbrowser (and in 'cookie-disabled' firefox):
//
// api:
//
// .clear() empties storage
// .each() loops storage (key, value) pairs
// .fetch() get a value by key
// .has() checks if there is a key set
// .ls() lists all keys
// .raw() string value actually stored
// .reload() reads in serialized data
// .rm() removes key(s)
// .set() setup value(s)
// .type() storage type used 'localStorage/globalStorage/userData'
// .valid() is storage engine setup correctly
//
;
((function(name, def, glob, doc) {
// add 'store' id to globals
this[name] = def(glob, doc);
}).call(
this, "store", function(glob, doc) {
// private (function) store version
var stclient;
var driver = {
// obj : storage_native{},
// type : storage_type
};
var engine = {
// read : (func),
// write : (func)
};
var _ = {
a: Array.prototype,
del: function(node) { // , ...fields
_.slc(arguments, 1).
forEach(function(field) {
delete this[field];
}, node);
return node;
},
each: function(array, callback, context) {
context ||
(context = array);
array.
some(function() {
return false === callback.apply(context, arguments);
});
return array;
},
hasown: Function.prototype.call.bind(Object.prototype.hasOwnProperty),
jsdc: JSON.parse, // decode
jsec: JSON.stringify, // encode
keys: Object.keys, // shimed .keys
ns: "storage5", // single property name to keep serialized storage data under
object: null, // parsed storage data
slc: Function.prototype.call.bind(Array.prototype.slice),
test: {
isemptyobj: function(node) {
for (var x in node)
return false;
return true;
},
isplainobj: function(node) {
return '[object Object]' == Object.prototype.toString.call(node);
},
},
testval: 'storage' + Math.random(), // test value for implementation check
rig: function(target, items) {
for (var field in items)
if (items.hasOwnProperty(field))
target[field] = items[field];
return target;
},
clone: function(node) {
return _.jsdc(_.jsec(node));
},
puts: function() {
engine.write(_.jsec(_.object));
},
};
stclient = function storage5() {
return arguments.length ?
storage5.set.apply(storage5, arguments) :
storage5.fetch();
};
// _init on load|ready
window.addEventListener('load', _init, false);
return _.rig(stclient, {
clear: function() {
return _.object = {}, _.puts(), this;
},
each: function(callback, context) {
context ||
(context = this.fetch());
_.each(this.ls(), function(field) {
return callback.call(context, field, this.fetch(field));
}, this);
return this;
},
fetch: function(key) {
return (arguments.length) ?
_.object[key] : _.clone(_.object);
},
has: function(name) {
return _.hasown(_.object, name);
},
ls: function() {
return _.keys(_.object);
},
raw: function() {
return engine.read();
},
reload: _load,
rm: function() {
_.del.apply(null, _.a.concat.apply([_.object], arguments));
return _.puts(), this;
},
set: function(input, value) {
var len = arguments.length;
var flag = 1;
if (len) {
if (_.test.isplainobj(input)) {
_.keys(input).
forEach(function(field) {
_.object[field] = input[field];
});
} else {
if (1 < len)
_.object[input] = value;
else
flag = 0;
}
flag && _.puts();
}
return this;
},
type: function() {
return driver.type || null;
},
valid: function() {
return !_.test.isemptyobj(driver);
},
});
function _init() {
var flag = 0;
var stnative;
if ("localStorage" in glob) {
try {
if ((stnative = glob["localStorage"])) {
// inits localStorage
_initlocst(stnative, driver, engine);
flag = 1;
}
} catch (e) {}
}
if (!flag) {
if ("globalStorage" in glob) {
try {
if ((stnative = glob["globalStorage"])) {
// inits globalStorage
_initglobst(stnative, driver, engine);
flag = 1;
}
} catch (e) {}
}
if (!flag) {
// inits userDataStorage
_initusrdatast(doc.createElement(_.ns), driver, engine);
}
}
// parse serialized storage data
_load();
}
function _initlocst(stnative, driver, engine) {
stnative[_.testval] = _.testval;
if (_.testval === stnative[_.testval]) {
try {
stnative.removeItem(_.testval);
} catch (e) {
try {
delete stnative[_.testval];
} catch (e) {}
}
driver.obj = stnative;
driver.type = "localStorage";
engine.read = function() {
return driver.obj[_.ns];
};
engine.write = function(stringvalue) {
driver.obj[_.ns] = stringvalue;
return stringvalue;
};
}
}
function _initglobst(stnative, driver, engine) {
var host = glob.location.hostname;
driver.obj = (/localhost/i).test(host) ?
stnative["localhost.localdomain"] : stnative[host];
driver.type = "globalStorage";
engine.read = function() {
return driver.obj[_.ns];
};
engine.write = function(stringvalue) {
driver.obj[_.ns] = stringvalue;
return stringvalue;
};
}
function _initusrdatast(node, driver, engine) {
try {
node.id = _.ns;
node.style.display = "none";
node.style.behavior = "url('#default#userData')";
doc.
getElementsByTagName("head")[0].
appendChild(node);
node.load(_.ns);
node.setAttribute(_.testval, _.testval);
node.save(_.ns);
if (_.testval === node.getAttribute(_.testval)) {
try {
node.removeAttribute(_.testval);
node.save(_.ns);
} catch (e) {}
driver.obj = node;
driver.type = "userData";
engine.read = function() {
return driver.obj.getAttribute(_.ns);
};
engine.write = function(stringvalue) {
driver.obj.setAttribute(_.ns, stringvalue);
driver.obj.save(_.ns);
return stringvalue;
};
}
} catch (e) {
doc.
getElementsByTagName("head")[0].
removeChild(node);
}
node = null;
}
function _load() {
try {
_.object = _.jsdc((engine.read() || engine.write("{}")));
} catch (e) {
_.object = {};
}
}
}, window, document));
//eof
Vanilla JS:
var printStorageBody = function () {
var body = document.querySelector("body");
var pre = document.createElement("pre");
body.innerHTML = "";
pre.innerText = JSON.stringify(localStorage, null, '\t');
body.appendChild(pre);
}
jQuery:
var printStorageBody = function () {
$("body").html("");
$("<pre>")
.text(JSON.stringify(localStorage, null, '\t'))
.appendTo("body");
}
I have a problem with return a value from an object.
my object looks like this.
function XYZ(date, startT)
{
var _date=date;
var _startT=startT;
this.get_date = function() {
return _date;
};
this.set_date = function(value) {
_date=value;
};
this.get_startT = function() {
return _startT;
};
this.set_startT = function(value) {
_startT=value;
};
this.toString()
return (_date + " " _startT);
}
then i create an Array like this
jsData[0] =new XYZ("2012-11-11","8:00");
jsData[1] = new XYZ("2012-03-03","8:00");
when i want to use get_date method it didn't return me the value but the get_startT method works fine.
When i show object with .toString method it also show me full object
Please help.
It works if you fix all the syntax errors:
function XYZ(date, startT) {
var _date=date;
var _startT=startT;
this.get_date = function() {
return _date;
};
this.set_date = function(value) {
_date=value;
};
this.get_startT = function() {
return _startT;
};
this.set_startT = function(value) {
_startT=value;
};
}
var jsData = [];
jsData[0] = new XYZ("2012-11-11","8:00");
jsData[1] = new XYZ("2012-03-03","8:00");
display("jsData[0].get_date() = " + jsData[0].get_date());
Output:
jsData[0].get_date() = 2012-11-11
Live Copy | Source
Other than obvious typos, here's what I did:
Put { and } around the function body.
Removed the this.toString() which was non-functional (a no-op, as you didn't store the result anywhere).
Removed the return at the end, because returning a string primitive out of a constructor function is another no-op.
Declared jsData.
Initialized jsData.
You appear to be missing a opening bracket { after
function XYZ(date, startT)
And one at the end of your code. (})
Try adding methods to the function prototype like this:
function XYZ(date, startT) {
this._date = date;
this._startT = startT;
}
XYZ.prototype.get_date = function() {
return this._date;
}
XYZ.prototype.set_date = function(value) {
this._date = value;
}
XYZ.prototype.get_startT = function() {
return this._startT;
}
XYZ.prototype.set_startT = function(value) {
this._startT = value;
}
XYZ.prototype.toString = function() {
return this._date + " " + this._startT;
}
var myXYZ = new XYZ("2012-11-11","8:00");
myXYZ.toString(); // "2012-11-11 8:00"
I tested that in the console and it outputs the final string correctly.