Многие в курсе, что в Javascript есть так называемые Getter'ы и Setter'ы. Это конструкции для отслеживания изменения значений свойств объекта, а так же возвращения этих значений. «С изнанки» объекта они выглядят как обычные функции:
Но раз это функции, их можно использовать как душе угодно!
Например, мы можем сделать конструктор, который упростит нашу работу с CSS некоего HTML элемента:
Теперь к кнопку с id «btn1» можно переместить, написав
Но прелесть Getter'ов и Setter'ов не только в упрощении повседневных задач, типа работы с CSS. Их можно использовать даже для изменения концепции самого языка:
Например, следующий пример выведет сообщение на экран:
Страшно? По-моему, очень. Главное в этом деле не дойти до абсурда. Есть этому и математическое применение:
Например, у нас есть объект Obj, у которого есть свойство value, а также свойство sin. Обращаясь к свойству sin, мы получаем синус от value. Соль в том, что с помощью Setter'а можно сделать наоборот. Тогда после изменения sin, изменится и value. Одним словом, если sin==0.5, то value=Math.PI/6.
Стоит отметить, что решение не вполне кроссбраузерное. Если хотите портировать все это на ваш любимыйInternet Explorer браузер, вам следует использовать __defineGetter__() и __defineSetter__(), либо методы, описанные здесь, и, в крайнем случае, здесь.
Но возможностей у Getter'ов и Setter'ов действительно много. Если скомбинировать все с тем же AJAX, можно добиться вполне кошерного вида вроде:
Это, конечно, введет в замешательство некоторых программистов, привыкших к тому, что операция присваивания не делает ничего, кроме присваивания (собственно, как и операция взятия значения). Одно но, придется что-то сделать с методами без параметров, типа .Destroy(), ибо писать Obj.Destroy = true уж точно никто не будет. Есть идея сделать что-то вроде тайм-аута по тикам, т.е. отслеживать каждый get и set. Это значит, что Obj.Destroy = 5 уничтожит объект через 5 get/set операций. Но это, понятное дело, уже излишний креатив.
var obj = {
get value() {
return 0;
},
set value(s) {
alert ("Go screw yourself!")
}
}
* This source code was highlighted with Source Code Highlighter.
Но раз это функции, их можно использовать как душе угодно!
Например, мы можем сделать конструктор, который упростит нашу работу с CSS некоего HTML элемента:
function $(object) {
if(typeof(object)=="string"){object=document.getElementById(object)};
object.__defineGetter__("x",function(){
return (parseInt(object.style.left))
}),
object.__defineSetter__("x",function(n){
object.style.left = n + 'px'
}),
object.__defineGetter__("y",function(){
return (parseInt(object.style.left))
}),
object.__defineSetter__("y",function(n){
object.style.top = n + 'px'
})
}
* This source code was highlighted with Source Code Highlighter.
Теперь к кнопку с id «btn1» можно переместить, написав
$("btn1").x = 56
.Но прелесть Getter'ов и Setter'ов не только в упрощении повседневных задач, типа работы с CSS. Их можно использовать даже для изменения концепции самого языка:
Например, следующий пример выведет сообщение на экран:
obj = {
set message(s) {
alert(s)
}
}
obj.message = "Hello, World!"
* This source code was highlighted with Source Code Highlighter.
Страшно? По-моему, очень. Главное в этом деле не дойти до абсурда. Есть этому и математическое применение:
Например, у нас есть объект Obj, у которого есть свойство value, а также свойство sin. Обращаясь к свойству sin, мы получаем синус от value. Соль в том, что с помощью Setter'а можно сделать наоборот. Тогда после изменения sin, изменится и value. Одним словом, если sin==0.5, то value=Math.PI/6.
obj = {
value: 0,
get sin() {
return Math.sin(this.value)
}
set sin(n) {
this.value = Math.asin(n)
}
}
* This source code was highlighted with Source Code Highlighter.
Стоит отметить, что решение не вполне кроссбраузерное. Если хотите портировать все это на ваш любимый
Но возможностей у Getter'ов и Setter'ов действительно много. Если скомбинировать все с тем же AJAX, можно добиться вполне кошерного вида вроде:
ajax.url = "script.php"
alert(ajax.result)
* This source code was highlighted with Source Code Highlighter.
Это, конечно, введет в замешательство некоторых программистов, привыкших к тому, что операция присваивания не делает ничего, кроме присваивания (собственно, как и операция взятия значения). Одно но, придется что-то сделать с методами без параметров, типа .Destroy(), ибо писать Obj.Destroy = true уж точно никто не будет. Есть идея сделать что-то вроде тайм-аута по тикам, т.е. отслеживать каждый get и set. Это значит, что Obj.Destroy = 5 уничтожит объект через 5 get/set операций. Но это, понятное дело, уже излишний креатив.