2012-10-21 12 views
13

Possible Duplicate:
If Javascript has first-class functions, why doesn’t this work?funkcja Alias ​​w javascript

Kiedy próbuję uczynić funkcję alias dla document.getElementById jak poniżej:

f = document.getElementById; 

ale gdy próbuję zadzwonić:

var e_fullname = f(“fullname”); 

Został twierdza błąd: Could not convert JavaScript argument

A poniżej jest OK:

var e_fullname = f.call(document, “funname”); 

Czy możesz mi powiedzieć, dlaczego?

+2

masz jakieś nietypowe cytaty. Z jakiego edytora korzystasz? – 0x499602D2

+8

@ Dawni prawdziwi programiści używają słowa –

+0

Nie sądzę, że ten problem, ponieważ edytor. Po prostu rozumiem, jak działa Javascript? – vietean

Odpowiedz

20

Istnieją cztery sposoby wywoływania funkcji:

  1. wywołanie funkcji: f(p1, p2)
  2. Metoda inwokacja: obj.f(p1, p2)
  3. Zastosuj lub wywołanie Zadzwoń: f.apply(obj, [p1, p2]), f.call(obj, p1, p2)
  4. Konstruktor inwokacja: new f(p1, p2)

We wszystkich tych przypadkach f jest po prostu odwołaniem (wskaźnikiem) do obiektu funkcji (obiekt z właściwością wewnętrzną [[Call]]). To, co powoduje, że zachowuje się inaczej we wszystkich tych przypadkach, jest sposób w jaki funkcja jest wywoływana i to ma duże znaczenie.

Tak, f jest tylko odniesieniem do obiektu getElementById, nie ma różnicy między document.getElementById i someOtherHTMLElement.getElementById; funkcja nie wstrzymuje odwołania do obiektu, który się do niej odwołuje.

Jeśli chcesz związać pewną „właściciel” obiektu, użyj metody bind:

var f = document.getElementById.bind(document); 
1

Można użyć bind

Creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function was called.

var f = document.getElementById.bind(document); 

Został on wprowadzony w ES5, więc zdawać sobie sprawę z przeglądarek nie obsługujących jeszcze tej wersji ECMAScript!

Jako alternatywę można zastosować metodę jQuery proxy, dodane w wersji 1.4

var f = ​$.proxy(document.getElementById, document); 

Albo można delcare f jako funkcji własnych (jest to rozwiązanie bardziej gadatliwy).

var f = function() { return document.getElementById(arguments); } 
+0

Chciałem tylko wskazać, że JavaScript Wersja, do której się odnosisz, jest specyficzna dla Mozilli. Jeśli rozważasz użycie innych przeglądarek, lepiej zapoznać się z wersją ECMAScript. '.bind' został wprowadzony w ES5. –

+0

Dzięki @FelixKling zmieniłem go w tekście. – clentfort

+1

Ten ostatni nie działa, argumenty nie mogą być ponownie przesyłane bezpośrednio w ten sposób. Musisz zrobić coś w stylu 'document.getElementById.apply (document, Array.prototype.slice.call (arguments));' –

5

getElementById to metoda na dokumencie. Aby go wywołać, interpreter musi mieć samą treść funkcji, obiekt, który ją wywoła (dokument w twoim przypadku) i argumenty.

Kiedy wykonujesz f = document.getElementById, kopiujesz ciało funkcji, ale nie obiekt, do którego chcesz go wywołać.

Kiedy to zrobić:

f.call(document, “funname”); 

Ty zapewniając zarówno obiektu, aby zadzwonić go i argumenty.

Jeśli chcesz mieć możliwość bezpośredniego wywoływania f, musisz jakoś tam umieścić obiekt "document". Najłatwiejszy to:

var f = function(name){return document.getElementById(name)} 

To tworzy zamknięcie, które zawiera wartość dokumentu dla ciebie.

Możesz również użyć funkcji bind(), aby zrobić to samo.