Browse Source

Implement Array.prototype.at() (#1613)

pull/1619/head
Kevin 3 years ago committed by GitHub
parent
commit
94992a4a8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      boa/src/builtins/array/mod.rs

38
boa/src/builtins/array/mod.rs

@ -86,6 +86,7 @@ impl BuiltIn for Array {
values_function, values_function,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
) )
.method(Self::at, "at", 1)
.method(Self::concat, "concat", 1) .method(Self::concat, "concat", 1)
.method(Self::push, "push", 1) .method(Self::push, "push", 1)
.method(Self::index_of, "indexOf", 1) .method(Self::index_of, "indexOf", 1)
@ -487,6 +488,43 @@ impl Array {
Ok(a.into()) 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)` /// `Array.prototype.concat(...arguments)`
/// ///
/// When the concat method is called with zero or more arguments, it returns an /// When the concat method is called with zero or more arguments, it returns an

Loading…
Cancel
Save