8.12.5 Put

2010-04-19

undefined [[Put]](P:String, V:mixed, Throw:Boolean)

This is an attribute method of object O. It is called with property P (string) and some value V. It will attempt to store V at O[P] and could throw a TypeError (but may ignore errors silently). If it doesn't throw an error it will return undefined, regardless of the result.

In the method, this is the object O.

Code: (Abstract Ecma)
function [[Put]](P, V, Throw){
if (this.[CanPut]](P) === false) {
if (Throw) throw TypeError;
return;
}
var ownDesc = this.[[GetOwnProperty]](P);
if (IsDataDescriptor(ownDesc)) {
var valueDesc = {[[Value]]: V}; // this is a property descriptor!
this.[[DefineOwnProperty]](P, valueDesc, Throw);
return;
}
var desc = this.[[GetProperty]](P); // own/inherited accessor pd, inherited data pd
if (IsAccessorDescriptor(desc)) {
var setter = desc.[[Set]]; // cannot be undefined
setter.[[Call]](this, V);
} else {
var newDesc = {[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false}; // PD
O.[[DefineOwnProperty]](P, newDesc, Throw);
}
}


So. First try whether you can actually write to P in the first place. If so, try to get the own property and try to write to that. Otherwise try to get any inherited property P and write to that. In the end the function returns, regardless of what happened. The function could throw an error if you cannot write to P and the Throw flag is true.

Note that host objects may add additional constraints to [[Put]]. Those objects should not allow a [[Put]] where the specifications definition of [[CanPut]] does not allow it.