When creating the functions: function abc:Test() == function abc.Test(self)
When calling the functions: abc:Test() == abc.Test(abc)
It’s just syntactic sugar. You could even mix those in-between each other and it would still work fine. The most important thing to know is that when you define a function with :, it injects a self argument as the first argument implicitly. And when you call a function with :, it also injects itself (the table it’s attached to) as self for the first argument.
self is the table itself, normally passed as the first argument.
local item = {}
item.foo = "1"
function item:test()
print(self.foo)
end
function item.test2(self)
print(self.foo)
end
print(item:test()) -- 1
print(item:test2()) -- 1
print(item.test2()) -- attempt to index nil with foo