ეხლახანს meebo.com – ზე შევიარე, და რატომღაც ვაკანსიების განყოფილებას გადავხედე, დამაინტერესა რა პოზიციებზე აქვს ვაკანსიები ამ კომპანიას… ერთერთი აღმოჩნდა javascript engineer (javascript ninja) და რატომღაც გადავხედე
პოსტში, ვაკანსიის აღწერის გარდა მითითებულია რამდენიმე JavaScript – თან დაკავშირებული შეკითხვა, და შევეცადე პასუხები გამეცა, ჩემის აზრით ეს დაგაინტერესებთ:
1. When does div.setAttribute(“###”) not equal div.###?
საკმაოდ მარტივი შეკითხვაა რადგან MDC – ს დოკუმენტაციაში პირდაპირ წერია, რომ, DOM ელემენტს ატრიბუტის შექმნის და მისთვის საწყისი მნიშნველობის მინიჭების აუცილებლობის შემთხვევაში უნდა გამოვიყენოთ el.setAttribute(attName, attValue); მეთოდი. ხოლო ამ ატრიბუტის მნიშვნელობის შემდეგი ცვლილებისათვის უნდა გამოვიყენოთ ელემენტის თვისება, ანუ: el.attName = attValue და არა setAttribute მეთოდი;
ციტატა დოკუმენტაციის გვერდიდან:
Using setAttribute() to modify certain attributes, most notably value in XUL and HTML and selected in HTML, works inconsistently, as the attribute specifies the default value. To access or modify the current values, you should use the properties. For example, use elt.value instead of elt.setAttribute(‘value’, val).
2. What’s the difference between these two statements:
a. var x = 3; b. x = 3;
ეს შეკითხვაც არ მიეკუთვნება რთულ კატეგორიას. var ქივორდის გამოყენება ცვლადის აღწერის წინ მისი სკოუპის(გლობალური, ფუნქციის, კლასის) ფიქსაციისათვის გამოიყენება. ხოლო თუ არარსებულ ცვლადს მივანიჭებთ მნიშვნელობას var – ის გამოყენების გარეშე, მაშინ ეს ცვლადი გლობალურ კონტექსტში მოხვდება.
3. What’s the difference between:
a. !!(obj1 && obj2) b. (obj1 && obj2)
ამ შემთხვევაში ნაჩვენებ ორ გამოსახულებას შორის მგონი არანაირი განსხვავება არ უნდა იყოს. a ვარიანტში, გამოსახულების წინ მითითებული ორი ძახილის ნიშანი(!!) ნიშნავს შემდეგს: მარჯვენა ძახილის ნიშანი (obj1 && obj2) გამოსახულების დაიყვანს boolean ტიპზე და შეცვლის მას საპირისპირო მნიშვნელობით(ანუ თუ გამოსახულების შედეგია false საპირისპირო მნიშვნელობა იქნება true და პირიქით), ხოლო მარცხენა ძახილის ნიშანი კვლავ შეცვლის ამ საპირისპირო მნიშვნელობას შესაბამისად.
a შემთხვევაში (obj1 && obj2) გამოსახულება ნებისმიერ შემთხვევაში დააბრუნების boolean ტიპის მნიშნველობას && – ის გამო, ხოლო ზემოთ აღწერილი ძახილის ნიშნების გამოყენება საბოლოო ჯამში მაინც იგივე შედეგს მოგვცემს.
რადან b შემთხვევაშიც a – ს მსგავსად, გამოსახულება აუცილებლად აბრუნებს boolean ტიპის მნიშვნელობას, ეს ნიშნავს იმას რომ ამ ორ გამოსახულებას შორის არანაირი განსხვავება არ არსებობს.
4. Write a one-line piece of JavaScript code that concatenates all strings passed into a function:
function concatenate(/*any number of strings*/) { var string = /*your one line here*/ return string; }
ეს შეკითხვა ძალიან საინტერესოა. პირობა მოითხოვს რომ, concatenate() ფუნქციისათვის გადაცემული ნებისმიერი რაოდენობის სტრიქონული ტიპის პარამეტრის კონკატენაცია მოხდეს ერთი სტრიქონი კოდით. JavaScript – ში ფუნქციის გამოძახების დროს, მას შეგვიძლია გადავცეთ ნებისმიერი რაოდენობის პარამეტრი. ფუნქციისათვის გადაცემული ყველა პარამეტრი ინახება arguments ობიექტში ჩამონათვალის სახით. ერთი შეხედვით arguments ობიექტი მასივს წააგავს, მაგრამ სინამდვილეში იგი ნამდვილი მასივი არ არის. გამომდინარე აქედან, არგუმენტების გაერთიანებას Array ობიექტის join() მეთოდის გამოყენებით ვერ შევძლებთ… რადგან arguments ობიექტს Array ობიექტის მეთოდები არ გააჩნია.
ამისათვის მოგვიწევს მსგავსი კოდის დაწერა:
function concatenate() {
var string = Array.prototype.join.call(arguments);
return string;
}
alert(concatenate('s1', 's2', 's3', 's4'));
გამოსავალი მდგომარეობს ფუნქციის call მეთოდის გამოყენებაში(იხ. პოსტი call და apply მეთოდების შესახებ).
პირველ რიგში Array ობიექტის join მეთოდს მივმართავთ prototype თვისების მეშვეობით. ხოლო შემდეგ ვიძახებთ ფუნქციის call მეთოდს, რომელსაც პირველ პარამეტრად გადაეცემა კონტექსტი. ამიტომ join() მეთოდის შესრულება მოხდება უშუალოდ arguments ობიექტის კონტექსტში, რაც თავის მხრივ join() მეთოდს წვდომას მისცემს arguments ობიექტის ყველა თვისებაზე. გამომდინარე იქედან რომ, arguments ობიექტი არის იტერირებადი, და მას გააჩნია length თვისება(რომელიც ასევე გააჩნია Array ობიექტს), join() მეთოდს ეძლევა იმის საშუალება რომ arguments ობიექტის ელემენტები დააჯგუფოს. შედეგად მივიღებთ ასეთ “s1,s2,s3,s4″ კონკატენირებულ სტრიქონს.
5. What do these two examples have in common?
Example 1:
var obj = document.getElementById('adiv'); document.getElementById('adiv').ptr = obj;Example 2:
function assignClick() { var el = document.createElement('div'); function handleClick() { el.innerHTML = 'clicked!'; } el.attachEvent("onclick", handleClick); }
ხო, ამ შეკითხვამ ცოტა არ იყოს დამაბნია, და არ ვიცი რამდენად სწორად მივხვდი. თუ თქვენს მოსაზრებებს მომაშველებთ ძალიან გამახარებთ
რამდენადაც მე ვვარაუდობ, პირველ მაგალითში DOM ელემენტის .ptr თვისებას უბრალოდ ვანიჭებთ obj ობიექტს.
მეორე მაგალითშიც იგივესთან უნდა გვქონდეს საქმე, რადგან attachEvent არის ივენთებთან მუშაობის IE – ს მოდელი რომელიც არცერთ სხვა ბრაუზერში არ გვხვდება. ნაჩვენებ კოდსა el.attachEvent(“onclick”, handleClick) და el.onclick = handleClick ამ კოდს შორის კი არანაირი განსხვავება არ არსებობს. W3C მოდელისგან განსხვავებით IE – ს attachEvent ზუსტად იგივეს აკეთებს რაც ელემენტის თვისებაზე ობიექტის მინიჭებაა(იხ. განსხვავება IE და W3C მოდელებს შორის). ამ განსხვავების საფუძველზე ვივარაუდე ეს პასუხი, თუმცა დარწმუნებული ნამდვილად არ ვარ.
Update: სწორი პასუხი იხილეთ კომენტარებში, მთელი წინა(წაშლილი) აბზაცი წარმოადგენს სრულ სისულელეს
ტეგები: IE Sucks, JavaScript
ბოლო ტესტი ყველაზე საინტერესო იყო
2
document.getElementById('adiv').ptr = obj;
ამ კოდის მტავარი აზრი მგონი ის იყო რომ იქმნებოდა “რეკურსიული”(არ ვიცი სხვანაირად რა ვუწოდო) პოინტერი ამ ობიექტში, ანუ obj იგივეა რაც obj.ptr, obj.ptr.ptr და ა.შ.
: D
IE6 Sucks – სთქო რომ ვამბობ ეტყობა დამავიწყდა
გიორგი,
ეგ არის ნამდვილი პრობლემა და არც მომსვლია თავში აზრად, ეტყობა გამთენიისას ტესტები არ უნდა აკეთო ადამიანმა
მხოლოდ IE6 – ში წარმოქმნის ეგ მემორი ლიკს(თუმცა ბოლო პატჩის მერე არც მანდ არის პრობლემა), Circular Reference ქვია მაგას და ორივე შემთხვევაში აბსოლუტურად ერთი და იგივე ხდება.
პირველ შემთხვევაში რაც შენ დაწერე ეგ არის.
მეორე შემთხვევაში იგივე ხდება დაახლოვებით რაც ამ პოსტში მაქვს აღწერილი.
საქმე იმაშია რომ კოდის ეს ნაწილი ყოველთვის ცირკულარულ რეფერენსს წარმოქმნის:
var el = document.createElement('div'); function handleClick() { el.innerHTML = 'clicked!'; }handleClick ფუნქციის სკოუპიდან, ფუნქციის გარეთ აღწერილი el დომ ელემენტი ჩანს, ხოლო მისი სკოუპის გარეთ ამ ელემენტის გა – null – ება არ ხდება, IE6 – ში კი ბოლო განახლებამდე გარბიჯ კოლექტორი მაგ შემთხვევაში შტერდებოდა
. შედეგად როგორც პირველ ასევე მეორე შემთხვევაში ზუსტად ერთსა და იმავე ეფექტს მივიღებთ.
ასეთი რამ რომ გავაკეთოთ:
el.attachEvent("onclick", handleClick); el = null;პრობლემა ავტომატურად მოხსნება.
დიდი მადლობა კარგი პასუხისთვის
როგორც ყოველთვის საინტერესო და საგანმანათლებლო თემა იყო სოსო