Ustawianie właściwej instancji obiektu w metodzie - bind
Co zrobić, żeby w metodzie była widoczna właściwa instancja obiektu?
(interpretuje: Internet Explorer 9, Firefox 4, Opera 12, Chrome 7)
Function.prototype.bind(thisArg) Function.prototype.call(thisArg, arg1, arg2... argn)
- Parametry:
- thisArg - wartość bieżącego obiektu
this
dostępnego w czasie wywołania wewnątrz ciała funkcji - arg1, arg2... argn - lista początkowych argumentów wywołania funkcji
- Wartość:
Function
- nowa instancja funkcji- Wyjątki:
TypeError
- nastąpiła próba wywołania na obiekcie, który nie jest funkcją
W asynchronicznych językach programowania bardzo często używa się tzw. funkcji zwrotnej. Na przykład możemy spróbować pobrać dane z zewnętrznego źródła, ale ponieważ odpowiedź nie pojawi się natychmiast, program kontynuuje normalnie dalsze działanie. Dzięki temu interfejs użytkownika nie zacina się w oczekiwaniu na odpowiedź z zewnętrznego źródła. Kiedy odpowiedź nadejdzie, zostanie wywołana właśnie wcześniej zdefiniowana funkcja zwrotna, która odbierze przesłane dane.
Taki sposób działania programu jest bardzo wydajny, ale często powoduje utratę kontekstu wywołania. W funkcji zwrotnej wartość obiektu bieżącego this
może nie być tym, czego się spodziewamy. Można temu zapobiec, używając wcześniej funkcji bind
. Dzięki niej w czasie wywołania naszej funkcji zwrotnej obiekt bieżący this
będzie zawierał zawsze podaną wartość. Możemy również uzupełnić początkowe argumenty funkcji, tak aby przy każdym późniejszym jej wywołaniu miały taką samą wartość, a dodatkowe argumenty były dołączane na końcu listy.
Przykład Function.prototype.bind
var Person = function (name) { this.name = name; }; Person.prototype.speak = function (volume, speech) { return this.name + " (" + volume + "): " + speech; }; var Computer = function (name) { this.name = name; }; Computer.prototype.execute = function (command, args) { return command.apply(this, args); }; var person = new Person("John"); var f = person.speak.bind(person, "loudly"); var computer = new Computer("HAL 9000"); computer.execute(f, ["Hello world!"]); // "John (loudly): Hello world!" var args = ["silently", "My mind is going. I can feel it."]; computer.execute(person.speak, args); // "HAL 9000 (silently): My mind is going. I can feel it." Function.prototype.bind.call(null, person); // TypeError Function.prototype.bind.call(undefined, person); // TypeError Function.prototype.bind.call("test", person); // TypeError Function.prototype.bind.call({}, person); // TypeError