goswami_sudipta
Mega Expert

Hello--

Many of us might have faced challenges when we tried to change the core business logic of ServiceNow's Script Include which is protected, read only. I believe below would help you overcoming that challenge. Please read through. 

 

Problem statement -

While ServiceNow is publishing new apps, they are also making scripts protected ensuring to keep the core of the business logic unchanged. However, if a customer is rigid to get something, we found ourselves in a problem as the base of business logic is protected. 

 

Possible solutions -

 In this situation, the most common but the poor solution we design is, duplicating the base script - Script Include (SI) - and alter the methods as our need and invoke the new SI's method. Though, we should go for this approach at the end when there are no other means to achieve the business need.

Please keep in mind that, though there could be alternatives available to achieve this based on scenarios, the initial step we should attempt is overriding the ServiceNow SI. This can be achieved by inheriting base class' properties (ServiceNow SI) in your custom SI. This will then provide us the ability to tweak the core logic.

 

Let me share an example to show how we can do it in ServiceNow.

 

Here how it works -

  • parentSI() – Let’s assume, that this SI is produced by ServiceNow and is protected, read-only
  • childSI() - This would be our custom SI class overriding the protected class i.e. parentSI() class
var parentSI = Class.create();
parentSI.prototype = {
    initialize: function(prm) {
		this._pStrVar1 = "parent";
		if (typeof prm != "undefined" && prm != "") {
			this._privateFun(prm);
		}		
    },

	_privateFun: function(prm) {
		this._pStrVar1 = "Original value: " + this._pStrVar1 + " New value: " + prm;
	},
	
	getParentClassValue: function() {
		return this._pStrVar1;
	},
	
    type: 'parentSI'
};
var childSI = Class.create();
childSI.prototype = Object.extendsObject(parentSI, {
    initialize: function(prm) {
		this._cStrPrm = prm;
		this._cStrVar1 = "child";
		if (typeof prm != "undefined" && prm != "") {
			parentSI.prototype.initialize.call(this, prm);
		}
    },
	
	getChildValues: function() {
		return this._cStrVar1;
	},
	
	alterParentClassVar: function() {
		if (typeof this._cStrPrm != "undefined" && this._cStrPrm != "") {
			return this.getParentClassValue();
		} else {
			this._pStrVar1 = "altering it from child";
			return this._pStrVar1;
		}
	},
    type: 'childSI'
});
/* Background script */

var v_oParentSI1 = new parentSI();
var v_oParentSI2 = new parentSI("abc");
var v_oChildSI1 = new childSI();
var v_oChildSI2 = new childSI("xyz");

gs.print(v_oParentSI1.getParentClassValue());	// parent
gs.print(v_oParentSI2.getParentClassValue());	// Original value: parent New value: abc
gs.print(v_oChildSI1.getChildValues()); 		// child
gs.print(v_oChildSI1.alterParentClassVar());	// altering it from child
gs.print(v_oChildSI2.alterParentClassVar());	// Original value: parent New value: xyz

 

If you look closely in above examples, the base class i.e. parentSI() is being inherited by childSI() and we can tweak the value of parent class' variable this._pStrVar1 and can call parent class’ method in childSI.alterParentClassVar(). In addition to this, I also illustrated that how parent class' constructor can be invoked from child class with parameters being passed.

I hope this would help you in addressing one of common problem

Thank you, Sudipta

Comments
dougconnell
Kilo Guru

I like the fact that you have shown a method of calling the parent constructor.

 

For ES5, there is a another pattern for inheritance which I slightly prefer:

See:  Classical Inheritance in JavaScript ES5 - DZone Web Dev

 

Personally I prefer composition to inheritance.

Version history
Last update:
‎06-11-2020 12:23 AM
Updated by: