After spending 3 hours trying to find the source of the
Object doesn't support property or method 'exec'
I am getting, which is spawning many more errors, I've narrowed it down to my function
Object.prototype.OwnPropsEqualTrue = function ( )
{
var true_props = [];
for ( var this_prop in this )
{
if ( this.hasOwnProperty(this_prop) && this.this_prop === true )
{
true_props.push(this_prop);
}
}
return true_props;
}
which is meant to act on objects are maps of strings to booleans, e.g.
{ "SomeBoolean" : true, "SomeOtherBoolean" : false, "IsInChicago" : false }
For some reason the presence of this function is causing the error I mentioned and pointing to the
if(isCurrentExternalUser=isExternalUser(),isCurrentExternalUser&&BindClickOnO365SettingsMenu(),isBizStampingDlg=!1,window.location.href.indexOf("IsDlg=1")>-1&&(window.location.href.search(/Upload.aspx/i)>-1||window.location.href.search(/UploadEx.aspx/i)>-1)?(isBizStampingDlg=!0,isUploadDialog=!0):isUploadDialog=!1,window.location.href.indexOf("IsDlg=1")>-1&&window.location.href.search(/aclinv.aspx/i)>-1?(isBizStampingDlg=!0,isSharingDialog=!0):isSharingDialog=!1,isRightToLeft=$("html:first").attr("dir")=="rtl"?!0:!1,uiVersion==15||!isBizStampingDlg)
line of a JavaScript library in SharePoint.
Can anyone try to help me understand what i'm doing wrong here? Browser is IE, btw.
If you must add a method to the Object prototype (and you probably shouldn't), add it with Object.defineProperty:
Object.defineProperty(Object.prototype, "ownTrueProperties", {
value: function() {
return Object.keys(this).filter(function(key) {
return this[key] === true;
}, this);
}
});
That'll make the property non-enumerable, so it won't mess up for ... in loops.
Related
The method element.scrollIntoView accepts one parameter. This parameter can be a boolean value or an object.
Currently, only Firefox supports the object syntax. I need to find a way to detect if the method allows an object to be passed.
The following is the code I'm trying to write:
var acceptsObjects = // part that I'm missing
if (acceptsObjects) {
element.scrollIntoView({ block: 'end', behavior: 'smooth' })
} else {
element.scrollIntoView(false)
}
My answer is quite late, but maybe it helps someone else:
function supportsScrollIntoViewOptions() {
var isSupported = false;
try {
var opts = {};
Object.defineProperty(opts, 'block', {
// define a getter on the opts object for the property 'block'
// if an object as the argument is supported, this function will be called and
// we can set `isSupported` to true
get: function() {
isSupported = true;
return 'nearest';
}
});
document.createElement('div').scrollIntoView(opts);
} catch(e) {}
return isSupported;
}
I have used var and old school method definitions for better backwards compatibility, as well as wrapped everything in a try { … } catch(e) { … }, which I’m not sure is necessary.
This was tested in Firefox 31.0, which returns false as well as Firefox 108.0.1 and Safari 15.5 which both return true. Even though Can I Use claims this feature is not supported in Safari 15.5 it works.
Please let me know if there are any improvements to my code.
According to https://github.com/jquery/jquery/blob/9434e03193c45d51bbd063a0edd1a07a6178d33f/src/event.js#L21-L27
There are two functions in event.js in jquery that return true and false:
from events.js
function returnTrue() {
return true;
}
function returnFalse() {
return false;
}
I know they are good. But I don't understand the reasoning for this.
Did you look and see where they are used?
They are used as a stubs for assignments that need a function that returns a boolean.
For example on line 670 of the same document:
this.isDefaultPrevented = returnTrue;
isDefaultPrevented is a function. Thus it needs a function that returns true as the default functionality.
Consider their usage:
// Events bubbling up the document may have been marked as prevented
// by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = src.defaultPrevented ||
// Support: Android < 4.0
src.defaultPrevented === undefined &&
src.getPreventDefault && src.getPreventDefault() ?
returnTrue :
returnFalse;
Do this or something similar across several functions. It's easier to type returnTrue, than have to spell out function() { return true; } every time, isn't it? Code reuse and readability.
I am creating a module that takes in several complicated JSON files and would like some code to give the user feedback if certain elements are absent.
Below is the way I am doing it now, but I cannot help to think there must be a cleaner, less hacky way.
var _und = require("underscore");
//this function takes a list of required attributes and ensures they are present
var check_req_attr = function(config, req_attr, callback) {
var config_attr = Object.keys(config);
var absent_attr = _und.difference(req_attr, config_attr); //slightly hacky code that checks to ensure config has correct vars
if (absent_attr.length !== 0) {
throw Error("missing following attributes from config:" + absent_attr);
} else {
callback();
};
};
It just feels...dirty. If there is no real elegant way to do it, I would be open to critiques on my code. Thanks!
Parse the JSON to JS.
var data = JSON.parse(theJson);
Use something like:
function hasKey(obj, key) {
return typeof obj[key] !== 'undefined';
};
function hasKeys(obj, keys) {
for (var i = 1, len = keys.length; i < len; i++) {
if (!hasKey(obj, keys[i])) {
return false;
};
};
return true;
};
Now you can simply do:
if (hasKeys(data, ["firstKey", "secondKey", "thirdKey"]) {
console.log("valid");
};
This should be the way to do it, using every and has:
if (_und.every(req_attr, function(attr) {
return _und.has(config, attr);
}))
throw new Error();
In a native environment, you would just use the in operator:
req_attr.every(function(attr){ return attr in config; })
I think your solution is actually quite elegant! No need for an anonymous function, and the loop (which must happen at some point, obviously) neatly abstracted away with difference.
Two suggestions:
I'd give the function a synchronous signature. No callback argument. There can't be any reason to go async if you honor the function signature (i.e. basing your answer on config and req_attr only).
I'd change the function to return the missing properties (attributes is wrong term). You could also add a requireProperties function that uses this "check" function that would throw if a property was missing. This allows for different kind of uses.
Why don't you try with something like:
obj = JSON.parse(json);
and then check
if(obj.YourProperty == undefined){
//do something..
}
Hope i understood your question.. It should work with complicated JSON files too.. Good luck ;)
You could also use the in operator (requiredAttr in obj):
function objHasAllRequiredAttrs(obj, attrNames) {
return attrNames.reduce(function(memo, attrName) {
return memo && (attrName in obj);
}, true);
}
objHasAllRequiredAttrs({foo:1}, ['foo']); // => true
objHasAllRequiredAttrs({bar:1}, ['foo']); // => false
I'm learning more about javascript OOP by rolling my own console.log variant with some extra features I want.
So far I have
debug = {
consoleAvailable : (typeof console == "object"),
reportToConsole : 0,
list : [],
setReporting : function(level){
this.reportToConsole = level;
return true;
},
log : function(){
if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function") console.log.apply(console, this.log.arguments);
this.list.push({'type':'log', 'msg':this.log.arguments});
return true;
},
};
This is all working nicely, but I don't want to have to list all of the log,error,warning etc functions. Instead I would like to be able to just type debug.[something] and for a function to interpret that [something] and execute it in the same way as I have the log function working.
Is this even possible? If so how do I go about it?
Here is some examples of what I would like to be able to do.
debug.setReporting(1); //yes, I want to print to console
debug.log('foo', 'bar', 'baz'); //arbitrary number of arguments (this is already working)
debug.error('qux'); //function I haven't named, but there is a console.error function
debug.arbitraryName([1, 2, 3]); //no function for console.arbitraryName (ideally it would just console.log the argument(s)
Edit
Ok, it looks like #Rob W's method is the way to go, however I am having trouble implementing. It seems that I am not passing the name of the function correctly or similar. I have a fiddle here showing the problem http://jsfiddle.net/xiphiaz/mxF4m/
Conclusion
It looks like there is too many browser quirks to get a truly generic debugger without writing browser specific code, so instead I have just listed my most used log functions (log, warning and error). This does give me the option to further customize result of each of these functions.
result:
debug = {
consoleAvailable : (typeof console == "object"),
reportToConsole : 0,
list : [],
setReporting : function(level){
this.reportToConsole = level;
return true;
},
log : function(){
if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function") console.log.apply(console, this.log.arguments);
this.list.push({type:'log', msg:this.log.arguments});
return true;
},
warn : function(){
if (this.reportToConsole>0 && this.consoleAvailable && typeof console.warn=="function") console.warn.apply(console, this.warn.arguments);
this.list.push({type:'warn', msg:this.warn.arguments});
return true;
},
error : function(){
if (this.reportToConsole>0 && this.consoleAvailable && typeof console.error=="function") console.error.apply(console, this.error.arguments);
this.list.push({type:'error', msg:this.error.arguments});
return true;
}
};
debug.setReporting(1);
debug.log('foo', 'bar', 'baz');
debug.error('qux');
debug.warn({test:"warning"});
console.log(debug.list);
You can get an array of all properties (including non-enumerable ones) using the Object.getOwnProprtyNames method. Then, enumerate through it, and check whether the console[key] is a function. If yes, extend your own object with the method.
Object.getOwnPropertyNames(console)
As for your last quesion, there's a non-standard __noSuchMethod__ method which intercepts calls to undefined functions.
I strongly recommend to use my first proposed method, because the console method will not magically grow bigger. It also makes debugging easier.
Long story short: I'm in a situation where I'd like a PHP-style getter, but in JavaScript.
My JavaScript is running in Firefox only, so Mozilla specific JS is OK by me.
The only way I can find to make a JS getter requires specifying its name, but I'd like to define a getter for all possible names. I'm not sure if this is possible, but I'd very much like to know.
Proxy can do it! I'm so happy this exists!! An answer is given here: Is there a javascript equivalent of python's __getattr__ method? . To rephrase in my own words:
var x = new Proxy({}, {
get(target, name) {
return "Its hilarious you think I have " + name
}
})
console.log(x.hair) // logs: "Its hilarious you think I have hair"
Proxy for the win! Check out the MDN docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Works in chrome, firefox, and node.js. Downsides: doesn't work in IE - freakin IE. Soon.
You can combine proxy and class to have a nice looking code like php:
class Magic {
constructor () {
return new Proxy(this, this);
}
get (target, prop) {
return this[prop] || 'MAGIC';
}
}
this binds to the handler, so you can use this instead of target.
Note: unlike PHP, proxy handles all prop access.
let magic = new Magic();
magic.foo = 'NOT MAGIC';
console.log(magic.foo); // NOT MAGIC
console.log(magic.bar); // MAGIC
You can check which browsers support proxy http://caniuse.com/#feat=proxy.
The closest you can find is __noSuchMethod__ (__noSuchMethod__ is deprecated), which is JavaScript's equivalent of PHP's __call().
Unfortunately, there's no equivalent of __get/__set, which is a shame, because with them we could have implemented __noSuchMethod__, but I don't yet see a way to implement properties (as in C#) using __noSuchMethod__.
var foo = {
__noSuchMethod__ : function(id, args) {
alert(id);
alert(args);
}
};
foo.bar(1, 2);
Javascript 1.5 does have getter/setter syntactic sugar. It's explained very well by John Resig here
It's not generic enough for web use, but certainly Firefox has them (also Rhino, if you ever want to use it on the server side).
If you really need an implementation that works, you could "cheat" your way arround by testing the second parameter against undefined, this also means you could use get to actually set parameter.
var foo = {
args: {},
__noSuchMethod__ : function(id, args) {
if(args === undefined) {
return this.args[id] === undefined ? this[id] : this.args[id]
}
if(this[id] === undefined) {
this.args[id] = args;
} else {
this[id] = args;
}
}
};
If you're looking for something like PHP's __get() function, I don't think Javascript provides any such construct.
The best I can think of doing is looping through the object's non-function members and then creating a corresponding "getXYZ()" function for each.
In dodgy pseudo-ish code:
for (o in this) {
if (this.hasOwnProperty(o)) {
this['get_' + o] = function() {
// return this.o -- but you'll need to create a closure to
// keep the correct reference to "o"
};
}
}
I ended up using a nickfs' answer to construct my own solution. My solution will automatically create get_{propname} and set_{propname} functions for all properties. It does check if the function already exists before adding them. This allows you to override the default get or set method with our own implementation without the risk of it getting overwritten.
for (o in this) {
if (this.hasOwnProperty(o)) {
var creategetter = (typeof this['get_' + o] !== 'function');
var createsetter = (typeof this['set_' + o] !== 'function');
(function () {
var propname = o;
if (creategetter) {
self['get_' + propname] = function () {
return self[propname];
};
}
if (createsetter) {
self['set_' + propname] = function (val) {
self[propname] = val;
};
}
})();
}
}
This is not exactly an answer to the original question, however this and this questions are closed and redirect here, so here I am. I hope I can help some other JS newbie that lands here as I did.
Coming from Python, what I was looking for was an equivalent of obj.__getattr__(key)and obj.__hasattr__(key) methods. What I ended up using is:
obj[key] for getattr and obj.hasOwnProperty(key) for hasattr (doc).
It is possible to get a similar result simply by wrapping the object in a getter function:
const getProp = (key) => {
const dictionary = {
firstName: 'John',
lastName: 'Doe',
age: 42,
DEFAULT: 'there is no prop like this'
}
return (typeof dictionary[key] === 'undefined' ? dictionary.DEFAULT : dictionary[key]);
}
console.log(getProp('age')) // 42
console.log(getProp('Hello World')) // 'there is no prop like this'