Accessing array/object attributes in Twig There are three methods for that:
object.attribute

object['attribute']

attr(object, 'attribute')

How are these different from each other?
{{ entry.title }}

compiles down to:
        echo twig_escape_filter($this-&gt;env, craft\helpers\Template::attribute($this-&gt;env, $this-&gt;source, (isset($context[&quot;entry&quot;]) || array_key_exists(&quot;entry&quot;, $context) ? $context[&quot;entry&quot;] : (function () { throw new RuntimeError('Variable &quot;entry&quot; does not exist.', 19, $this-&gt;source); })()), &quot;title&quot;, []), &quot;html&quot;, null, true);

...and
    {{ entry['title'] }}

compiles down to:
        echo twig_escape_filter($this-&gt;env, craft\helpers\Template::attribute($this-&gt;env, $this-&gt;source, (isset($context[&quot;entry&quot;]) || array_key_exists(&quot;entry&quot;, $context) ? $context[&quot;entry&quot;] : (function () { throw new RuntimeError('Variable &quot;entry&quot; does not exist.', 20, $this-&gt;source); })()), &quot;title&quot;), &quot;html&quot;, null, true);

...and
    {{ attribute(entry, 'title') }}

compiles down to:
        echo twig_escape_filter($this-&gt;env, craft\helpers\Template::attribute($this-&gt;env, $this-&gt;source, (isset($context[&quot;entry&quot;]) || array_key_exists(&quot;entry&quot;, $context) ? $context[&quot;entry&quot;] : (function () { throw new RuntimeError('Variable &quot;entry&quot; does not exist.', 21, $this-&gt;source); })()), &quot;title&quot;, [], &quot;array&quot;), &quot;html&quot;, null, true);

If they look similar, that's because... they are identical in terms of the PHP code they compile down to.
So the difference is... whichever one uses the fewest keystrokes to type.