Skip to content

Commit

Permalink
Implement Array.prototype.at() (#1613)
Browse files Browse the repository at this point in the history
  • Loading branch information
nekevss authored Oct 3, 2021
1 parent d3c5aea commit 94992a4
Showing 1 changed file with 38 additions and 0 deletions.
38 changes: 38 additions & 0 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ impl BuiltIn for Array {
values_function,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.method(Self::at, "at", 1)
.method(Self::concat, "concat", 1)
.method(Self::push, "push", 1)
.method(Self::index_of, "indexOf", 1)
Expand Down Expand Up @@ -487,6 +488,43 @@ impl Array {
Ok(a.into())
}

///'Array.prototype.at(index)'
///
/// The at() method takes an integer value and returns the item at that
/// index, allowing for positive and negative integers. Negative integers
/// count back from the last item in the array.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype.at
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at
pub(crate) fn at(this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult<JsValue> {
//1. let O be ? ToObject(this value)
let obj = this.to_object(context)?;
//2. let len be ? LengthOfArrayLike(O)
let len = obj.length_of_array_like(context)? as i64;
//3. let relativeIndex be ? ToIntegerOrInfinity(index)
let relative_index = args.get_or_undefined(0).to_integer_or_infinity(context)?;
let k = match relative_index {
//4. if relativeIndex >= 0, then let k be relativeIndex
//check if positive and if below length of array
IntegerOrInfinity::Integer(i) if i >= 0 && i < len => i,
//5. Else, let k be len + relativeIndex
//integer should be negative, so abs() and check if less than or equal to length of array
IntegerOrInfinity::Integer(i) if i < 0 && i.abs() <= len => len + i,
//handle most likely impossible case of
//IntegerOrInfinity::NegativeInfinity || IntegerOrInfinity::PositiveInfinity
//by returning undefined
_ => return Ok(JsValue::undefined()),
};
//6. if k < 0 or k >= len,
//handled by the above match guards
//7. Return ? Get(O, !ToString(𝔽(k)))
obj.get(k, context)
}

/// `Array.prototype.concat(...arguments)`
///
/// When the concat method is called with zero or more arguments, it returns an
Expand Down

0 comments on commit 94992a4

Please sign in to comment.