My question:
var nsPreferences = {
property1:"",
get mPrefService()
{
return Components.classes["#mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
},
setBoolPref: function (aPrefName, aPrefValue)
{
try
{
this.mPrefService.setBoolPref(aPrefName, aPrefValue);
}
catch(e)
{
}
},
getBoolPref: function (aPrefName, aDefVal)// Prefs.jsで使用
{
try
{
return this.mPrefService.getBoolPref(aPrefName);
}
catch(e)
{
return aDefVal != undefined ? aDefVal : null;
}
return null; // quiet warnings
},
};
In this object nsPreferences, what is this "get mPrefService(){}"? This is the first time I've seen this kind of syntax in javascript object. Would anyone tell me about this syntax?
It's a getter function. It will look like a variable when you read it:
var someService = nsPreferences.mPrefService;
It calls that function without using the regular invocation parens. You can also use the set operator to create a "setter" function for the same property:
set mPrefService(val){
this.actualVal = val;
},
nsPreferences.mPrefService = "service";
Related
I am quite confused by the following code. Why is "set:" instead the return statement? How does one call upon the set function? Thanks
BrainBrowser.createTreeStore = function() {
var tree = {};
return {
set: function() {
var value = arguments[arguments.length - 1];
},
It's kind of setter/getter define for createTreeStore, use it if you want more behavior when user set a value (or read value) of this object.
For example:
Object.defineProperty(document.body, "description", {
get : function () {
console.log("You are reading my value!!!");
return this.desc;
},
set : function (val) {
console.log("Thanks for new value!");
this.desc = val;
}
});
Usage:
document.body.description = "Content container";
Open console you will see the log:
Thanks for new value!
Read more here: http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/
I'm not that good with Javascript, so I'm not sure why I can't call the function dgnProcessesFilter like this.
var conditions = this.dgnProcessesFilter(item.proc_id, "proc_id");
The error im getting is Uncaught TypeError: this.dgnProcessesFilter is not a function
Just a few line up from that I have the function deceleration.
dgnProcessesFilter:function(id, type){
if(type == "site_id"){
return _dgnProceses.filter((process)=>process.site_id==id);
}
if(type == "proc_id"){
return _dgnProceses.filter((process)=>process.proc_id==id);
}
},
and in another function I also call that function, but with a immediate RETURN on the result, and it works just fine.
Why is this, can someone please help me and explain why maybe.
Bellow the call to this function woks fine.
getDgnProcesses: function(siteSelector) {
if(siteSelector.isNaN ){
if(siteSelector) {
return this.dgnProcessesFilter(siteSelector, "site_id");
} else {
return util.cloneArray(_dgnProceses || []);
}
} else {
if(siteSelector) {
var selectedSite = this.getSite("description", siteSelector);
if(selectedSite){
if (selectedSite.hasOwnProperty("site_id")) {
return this.dgnProcessesFilter(selectedSite.site_id, "site_id");
}
} else {
return [];
}
} else {
return util.cloneArray(_dgnProceses || []);
}
}
},
update
the call is from a search component
the store in included
_searchDiagnosis: function() {
this.setState({foundDiagnosis: this.state.searchValue ? DiagnosisStore.getDiagnosisSearch(this.state.searchValue).bind(DiagnosisStore) : [] });
},
I just tried the .bind(DiagnosisStore), but it did not seem to do the job.
all the functions are enclosed in the following.
var DiagnosisStore = assign({}, EventEmitter.prototype, {...}
I think you are loosing the lexical binding of 'this' at some point. If you are using ES6 or a transpiler (like Babel) try to use the "arrow" function notation to keep the value of 'this' of the surrounding code.
Here these is a blog post explaining arrow functions https://toddmotto.com/es6-arrow-functions-syntaxes-and-lexical-scoping/
Use also the new ES6 method declaration to be sure that 'this' is the object that contains the method:
getDgnProcesses(siteSelector) {
},
In javascript using an object parameter is my preferred way of working with functions. To check that a function has the required parameters I either (Solution 1) loop through all the object parameters properties and throw an error or (Solution 2) wait until a required property is needed and throw an error. Solution two seems efficient but I have to throws in multiple places in the function. Solution 1 seems pragmatic but should probably be a reusable piece of code. Is there another solution I should be looking at?
You can actually do this
var propsNeeded = ["prop1", "prop2", "blah", "blah", "blah"],
obj = {
prop1: "Hi"
}
function hasRequiredProperties(props, obj){
return Object.keys(obj).sort().join() == propsNeeded.sort().join();
}
console.log(hasRequiredProperties(propsNeeded, obj)); // false
You can check for single properties like
function hasProperty(propName, obj){
return obj.hasOwnProperty(propName);
}
For consistency I would create require method and use it always when some property is required.
var require = function (key, object) {
if (typeof object[key] === 'undefined') {
throw new Error('Required property ' + key + ' is undefined');
}
};
I would test if required property exists as soon as I'm certain that property is needed. Like this:
var example = function (args) {
require('alwaysRequired', args);
// some code here which uses property alwaysRequired
if (args.something) {
require('sometimesRequired', args);
// some code here which uses property sometimesRequired
}
};
Using #Amit's answer I'd probably add a method to Object itself:
Object.prototype.hasAllProperties = function(props, fire){
var result = Object.keys(this).sort().join() == propsNeeded.sort().join();
if (fire && !result){
throw new Error('Object does not define all properties');
}
return result;
}
and in your function:
function someFunction(myObject){
var objComplete = myObject.hasAllProperties(["prop1", "prop2", "prop3"], false);
}
Update:
After noticing the problem with #Amit's original answer, here's what I suggest:
Object.prototype.hasAllProperties = function(props, fire){
var result = true;
$(props).each(function(i, e){
if (!this.hasOwnProperty(e) ) {
result = false;
return false;
}
});
if (fire && !result){
throw new Error('Object does not define all properties');
}
return result;
}
This is just a general case of checking for presence of keys on a object, which can be done easily enough with
requiredParams.every(function(prop) { return prop in paramObj; })
It almost reads like natural language. "Taking the required parameters, is EVERY one of them IN the parameter object?".
Just wrap this in function checkParams(paramObj, requiredParams) for easy re-use.
More generally, this is the problem of asking if one list (in this case the list of required parameters) is included in another list (the keys on the params object). So we can write a general routine for list inclusion:
function listIncluded(list1, list2) {
return list1.every(function(e) { return list2.indexOf(e) !== -1; });
}
Then our parameter-checking becomes
function checkParams(paramObj, requiredParams) {
return listIncluded(requiredParams, Object.keys(paramObj));
}
If you want to know if object has at least some properties you can use this function without third parameter:
function hasRequiredProperties(propsNeeded, obj, strict) {
if (strict) return Object.keys(obj).sort().join() == propsNeeded.sort().join();
for (var i in propsNeeded ) {
if (!obj.hasOwnProperty(propsNeeded[i])) return false;
}
return true;
};
Example:
options = {url: {
protocol: 'https:',
hostname: 'encrypted.google.com',
port: '80'
}
};
propsNeeded = ['protocol', 'hostname'];
hasRequiredProperties(propsNeeded, options.url); // true
hasRequiredProperties(propsNeeded, options.url, true); // false
I was wondering if there was a way to use the get function in the url object below to generate property without wrapping it in an anonymous function.
It may be because I am just starting to dig into JavaScript after starting with jQuery, but something seems weird about wrapping a property in a anonymous function just to concatenate a string.
Current Object
var app = {
settings: {
webservice: 'http://abc.com/webservice/',
url: {
get: function (method) {
return app.settings.webservice + method;
},
caseSearch: function () {
return this.get('GetCases');
},
tipSearch: function () {
return this.get('GetTips');
},
propertySearch: function () {
return this.get('GetProperty');
}
}
}
};
Current
var url = app.settings.url.caseSearch();
Proposed
var url = app.settings.url.caseSearch;
I want to use the execAsync function here:
https://developer.mozilla.org/en/Storage#Asynchronously
and I want to pass values between handleResult and handleCompletion. Something like
statement.executeAsync({
handleResult: function(aResultSet) {
VALUE = 1
},
handleCompletion: function(aReason) {
print(VALUE);
}
});
What's the best way to do it?
var value;
statement.executeAsync({
handleResult : function(aResultSet) {
value = 1;
},
handleCompletion : function(aReason) {
print(value);
}
});
Well the obvious thing to notice is that you're passing an object to executeAsync. (In particular, it's a mozIStorageStatementCallback, so it should have a handleError method too.) So you can easily associate properties specific to that object with the object, using the "this" keyword:
statement.executeAsync({
value: 1,
handleResult: function(aResultSet) {
this.value = 0;
},
handleError: function(aError) {
this.value = 2;
},
handleCompletion: function(aReason) {
print(this.value);
}
});