How does this look:
Edit: Added explanatory comments.
function T() {
this.learningPlan = { learnerType : "aaa" };
this.setVal = function(p, v) {
// Split the property string into its "parts"
// thus "learningPlan.learnerType" becomes ["learningPlan","learnerType"]
var ps = p.split(".");
// Remove and capture the "last" (right-most) property
// From ["learningPlan","learnerType"] this would be "learnerType"
// leaving the array with ["learningPlan"]
var lastProp = ps.pop();
// Work "down" the object finding each level object finally returning
// the property object containing the property you wish to set
var o = ps.reduce(function(a,e) {
// This checks that each object["property"] exists and if
// it doesn't then it creates an empty object so that it can
// continue traversing down the property hierarchy.
// Given the property string "learningPlan.learnerType" if the
// property this.learningPlan didn't exist then attempting to
// reference this.learningPlan.learnerType would throw an error
// since learnerType is not a property of undefined. This is, I
// believe, the error you are experiencing. Using (a[e] || {})
// ensures that a[e] references something so that traversal
// can continue.
a[e] = (a[e] || {});
// This simply returns the property so that the reduce can keep
// moving through the array
return a[e];
}, this);
// Finally, we set the value for the last property in our string.
// The above reduce would walk down 'this' finding/setting each
// property until it reached the last string we left in our array
// after the pop and thereby returning a reference to that property
// into our variable "o". We then use the last property string as a
// property of "o" to set our value.
o[lastProp] = v;
};
}
It will allow you to do things like:
var t = new T();
t.setVal("learningPlan.learnerType", "def");