| @@ -51,8 +51,8 @@ | |||||
| */ | */ | ||||
| function primitiveHasOwnProperty (primitive, propName) { | function primitiveHasOwnProperty (primitive, propName) { | ||||
| return ( | return ( | ||||
| typeof primitive !== 'object' | |||||
| && primitive !== undefined | |||||
| primitive != null | |||||
| && typeof primitive !== 'object' | |||||
| && primitive.hasOwnProperty | && primitive.hasOwnProperty | ||||
| && primitive.hasOwnProperty(propName) | && primitive.hasOwnProperty(propName) | ||||
| ); | ); | ||||
| @@ -408,6 +408,12 @@ | |||||
| * | * | ||||
| * This is specially necessary for when the value has been set to | * This is specially necessary for when the value has been set to | ||||
| * `undefined` and we want to avoid looking up parent contexts. | * `undefined` and we want to avoid looking up parent contexts. | ||||
| * | |||||
| * In the case where dot notation is used, we consider the lookup | |||||
| * to be successful even if the last "object" in the path is | |||||
| * not actually an object but a primitive (e.g., a string, or an | |||||
| * integer), because it is sometimes useful to access a property | |||||
| * of an autoboxed primitive, such as the length of a string. | |||||
| **/ | **/ | ||||
| while (intermediateValue != null && index < names.length) { | while (intermediateValue != null && index < names.length) { | ||||
| if (index === names.length - 1) | if (index === names.length - 1) | ||||
| @@ -420,6 +426,19 @@ | |||||
| } | } | ||||
| } else { | } else { | ||||
| intermediateValue = context.view[name]; | intermediateValue = context.view[name]; | ||||
| /** | |||||
| * Only checking against hasProperty, which always returns false if | |||||
| * context.view is not an object. Deliberately omitting the check | |||||
| * against primitiveHasOwnProperty if dot notation is not used. | |||||
| * | |||||
| * Consider this example: | |||||
| * Mustache.render("{{#length}}{{length}}{{/length}}", {length: "hello"}) | |||||
| * | |||||
| * If we were to check also against primitiveHasOwnProperty, as we do | |||||
| * in the dot notation case, then render call would return 5, rather | |||||
| * than the expected "hello". | |||||
| **/ | |||||
| lookupHit = hasProperty(context.view, name); | lookupHit = hasProperty(context.view, name); | ||||
| } | } | ||||