окончательный метод javascript - PullRequest
2 голосов
/ 27 апреля 2011

Может ли метод в javascript быть окончательным?Как избежать его переопределения подклассом?

Ответы [ 3 ]

6 голосов
/ 27 апреля 2011

Вы можете использовать defineProperty , для чего член вы хотите обезопасить.

Майк упомянул атрибут configurable для предотвращения переопределения - удалить. Я тоже добавляю это.

function final(obj, members) {
    for (var i = 0; i < members.length; i++) {
        var m = members[i];
        if (obj.hasOwnProperty(m)) {
            Object.defineProperty(obj, m, { 
                value: obj[m],
                writable: false,
                configurable: false 
            });
        }
    }
    return obj;
}
var obj = { foo: "bar" };
obj = final(obj, ["foo"]);

obj.foo = ""; // output will be empty but
obj.foo // now output's still bar.

Другой вариант

Object.freeze . Но он защищает всех членов объекта.

var obj = { foo: "bar" };
obj = Object.freeze(obj);

obj.foo = ""; // output is empty
obj.foo // output is still "bar".
6 голосов
/ 27 апреля 2011

В традиционном смысле нет, вы не можете иметь закрытые / защищенные методы или не допускать их переопределения.

Однако вы можете инкапсулировать методы в области видимости, а затем просто не открывать их.их:

function foo(){
    function bar(){
        // private function
    }

    this.doSomething = function(){
        bar();
    }
}

Это как можно ближе.Недавно я написал статью об этом: http://www.htmlgoodies.com/primers/jsp/article.php/3600451/Javascript-Basics-Part-8.htm

Вы также можете использовать __defineGetter__ и __defineSetter__ для предотвращения доступа, но это не кросс-браузер на 100%.

var x = {};
x.__defineGetter__('foo', function(){ return 10; });
x.__defineSetter__('foo', function(){});

x.foo = 'bar';
x.foo; // 10
1 голос
/ 27 апреля 2011

Насколько я знаю, в языке нет способа навязать окончательность свойств объекта. Вы должны обеспечить это с вашей стороны. Один из способов быть «довольно уверенным» - использовать соглашение об именах, которое крайне маловероятно для использования в подклассе. что-то вроде

someobject.__property__

Вероятно, будет работать довольно хорошо. Другой вариант - использовать функцию hasOwnProperty (), чтобы определить, имеет ли родительский объект уже свойство, перед тем, как перезаписать его чем-то другим.

...