Я создал прототипный метод, который использует classList
, если это возможно, и прибегает к indexOf
:
Element.prototype.hasClass = Element.prototype.hasClass ||
function(classArr){
var hasClass = 0,
className = this.getAttribute('class');
if( this == null || !classArr || !className ) return false;
if( !(classArr instanceof Array) )
classArr = classArr.split(' ');
for( var i in classArr )
// this.classList.contains(classArr[i]) // for modern browsers
if( className.split(classArr[i]).length > 1 )
hasClass++;
return hasClass == classArr.length;
};
///////////////////////////////
// TESTS (see browser's console when inspecting the output)
var elm1 = document.querySelector('p');
var elm2 = document.querySelector('b');
var elm3 = elm1.firstChild; // textNode
var elm4 = document.querySelector('text'); // SVG text
console.log( elm1, ' has class "a": ', elm1.hasClass('a') );
console.log( elm1, ' has class "b": ', elm1.hasClass('b') );
console.log( elm1, ' has class "c": ', elm1.hasClass('c') );
console.log( elm1, ' has class "d": ', elm1.hasClass('d') );
console.log( elm1, ' has class "a c": ', elm1.hasClass('a c') );
console.log( elm1, ' has class "a d": ', elm1.hasClass('a d') );
console.log( elm1, ' has class "": ', elm1.hasClass('') );
console.log( elm2, ' has class "a": ', elm2.hasClass('a') );
// console.log( elm3, ' has class "a": ', elm3.hasClass('a') );
console.log( elm4, ' has class "a": ', elm4.hasClass('a') );
This is a test string
@@variables
не являются переменными класса. Они являются переменными иерархии классов , то есть они распределяются между всей иерархией классов, включая все подклассы и все экземпляры всех подклассов. (Было высказано предположение, что нужно думать о @@variables
больше как $$variables
, потому что у них на самом деле больше общего с $globals
, чем с @ivars
. Таким образом, это меньше путаницы. Другие пошли дальше и предлагают, чтобы они должен быть просто удален с языка.)
Ruby не имеет переменных класса в том смысле, что, скажем, Java (там, где они называются статическими полями), имеет их. Это не переменные класса , потому что классы также являются объектами, поэтому они могут иметь переменные instance , как и любой другой объект. Все, что вам нужно сделать, это удалить посторонние @
s. (И вам нужно будет предоставить метод доступа для переменной экземпляра класса.)
class A
def self.init config
@config = config
end
def self.config # This is needed for access from outside
@config
end
def config
self.class.config # this calls the above accessor on self's class
end
end
Давайте немного упростим это, так как A.config
явно просто атрибут_reader:
class A
class << self
def init config
@config = config
end
attr_reader :config
end
def config
self.class.config
end
end
И, на самом деле, A.init
- просто писатель с забавным именем, поэтому переименуем его в A.config=
и сделаем его автором, что, в свою очередь, означает, что наша пара методов теперь просто пара аксессуаров. (Так как мы изменили API, тестовый код также должен измениться, очевидно.)
class A
class << self
attr_accessor :config
end
def config
self.class.config
end
end
class B < A; end
class C < A; end
B.config = "bar"
p B.new.config # => "bar"
p C.new.config # => nil
C.config = "foo"
p B.new.config # => "bar"
p C.new.config # => "foo"
Однако я не могу поколебать ощущение, что в дизайне есть что-то более фундаментально, если вам это нужно вообще.