I am studying JavaScript, and I came across an issue, which I present below, I found several ways to solve a same case in JavaScript, and show which one I chose. I would like to know if they know other ways, and how best to deal with this kind of situation, letting the compiler work as I did would even be a good way to handle the issue or am I wrong?
// Utilizando a sintaxe de módulos, AssetPackage está
// em um arquivo diferente de PackageManager
function AssetPackage(name, assets) {
this.name = name;
this.assets = assets;
}
function PackageManager() {
this.packages = {};
}
I can not let objects that are not packages be added a packages, as this could make the API work poorly. I imagined the following way to solve this:
Way 1 - instanceof
// Importo AssetPackage
PackageManager.prototype.addPackage = function(assetPackage) {
if (!this.isAssetPackage(assetPackage))
return false;
this.packages[assetPackage.name] = assetPackage;
}
PackageManager.prototype.addPackages = function(assetPackages) {
if (!this.isAssetPackage(assetPackage))
return false;
for(let i = 0; i < assetPackages.length; i++)
this.packages[assetPackages[i].name] = assetPackages[i];
}
PackageManager.prototype.isAssetPackage = function(val) {
return (val instanceof AssetPackage);
}
Way 2 - Verifying properties
// Não importo AssetPackage
PackageManager.prototype.addPackage = function(assetPackage) {
if (!assetPackage.name || !assetPackage.assets)
return false;
this.packages[assetPackage.name] = assetPackage;
}
PackageManager.prototype.addPackages = function(assetPackages) {
for(let i = 0; i < assetPackages.length; i++)
if (!assetPackages.name || !assetPackages.assets)
continue;
this.packages[assetPackages[i].name] = assetPackages[i];
}
Way 3 - Checking properties and assigning only them
// Não importo AssetPackage
PackageManager.prototype.addPackage = function(assetPackage) {
if (!assetPackage.name || !assetPackage.assets)
return false;
this.packages[assetPackage.name] = {
name: assetPackage.name,
assets: assetPackage.assets
};
}
PackageManager.prototype.addPackages = function(assetPackages) {
for(let i = 0; i < assetPackages.length; i++)
if(!assetPackages.name || !assetPackages.assets)
continue;
this.packages[assetPackages[i].name] = {
name: assetPackages[i].name,
assets: assetPackages[i].assets
};
}
Way 4 - Checking Properties and Passing an Object
// Não importo AssetPackage
PackageManager.prototype.addPackage = function(assetPackage) {
if (!this.isObject(assetPackage) || !assetPackage.name || !assetPackage.assets)
return false;
this.packages[assetPackage.name] = {
name: assetPackage.name,
assets: assetPackage.assets
};
}
PackageManager.prototype.addPackages = function(assetPackages) {
if (!Array.isArray(assetPackages))
return false;
for(let i = 0; i < assetPackages.length; i++)
if(!this.isObject(assetPackages) || !assetPackages[i].name || !assetPackages[i].assets)
continue;
this.packages[assetPackages[i].name] = {
name: assetPackages[i].name,
assets: assetPackages[i].assets
};
}
PackageManager.prototype.isObject = function(val) {
return (typeof val === "object" && val !== null);
}
Way 5 - constructor.name
PackageManager.prototype.addPackage = function(assetPackage) {
if (!isAssetPackage(assetPackage))
return false;
this.packages[assetPackage.name] = assetPackage;
}
PackageManager.prototype.addPackages = function(assetPackages) {
if (!isAssetPackage(assetPackage))
return false;
for(let i = 0; i < assetPackages.length; i++)
this.packages[assetPackages[i].name] = assetPackages[i];
}
PackageManager.prototype.isAssetPackage = function(val) {
return (getType(val) === 'AssetPackage');
}
PackageManager.prototype.getType = function (o) {
return o && o.constructor && o.constructor.name;
}
Way 6 - The chosen one. Do not do any checking! let the compiler work.
// Importo AssetPackage
PackageManager.prototype.addPackage = function(assetPackage) {
this.packages[assetPackage.name] = assetPackage.assets;
}
PackageManager.prototype.addPackages = function(assetPackages) {
for(let i = 0; i < assetPackages.length; i++)
this.packages[assetPackages[i].name] = assetPackages[i].assets;
}
// ou
PackageManager.prototype.addPackage = function(assetPackage) {
this.packages[assetPackage.name] = {
name: assetPackage.name,
assets: assetPackage.assets
};
}
PackageManager.prototype.addPackages = function(assetPackages) {
for(let i = 0; i < assetPackages.length; i++)
this.packages[assetPackages[i].name] = {
name: assetPackages[i].name,
assets: assetPackages[i].assets
};
}
I chose to let the compiler work for the following reasons, if I return a "false" or whatever it is to return to the API user, he could simply ignore the false by inattention, this would cause errors in his code if he did not check correctly return the API functions, already letting the compiler work, your code would simply not compile and it would warn with an error, probably undefined property or something, and a compile error it can not ignore. This would avoid careless mistakes.