在C ++和Java(例如C ++和Java)等传统的面向对象的编程语言中,我们有一个保留的关键字private
,用于创建类的私人成员。但是,在JavaScript的情况下,场景大不相同,那里没有像private
这样的关键字。
考虑以下示例
const Book = function(isbn){
this.ISBN=isbn
this.getISBN=function(){
console.log(`ISBN number is ${this.ISBN}`)
}
}
const book1 = new Book(123)
book1.ISBN = 987
book1.getISBN() // ISBN number is 987
在上面的示例中,我们可以看到ISBN数字可以轻松地从Book
构造函数外部操纵。
因此,没有封装和数据隐藏,这对于松动耦合,代码可维护性和更好的代码管理非常重要。
现在,我们如何创建私人成员,以便仅在构造函数函数中访问它们?
答案是:关闭
JavaScript提供了封闭的概念,这意味着函数可以访问其定义的环境,而不是称为它们的环境。
查看下面的代码示例:
const Book = function(isbn){
let ISBN // private attribute
function checkISBN(x){ // private method
x=x+''
if(x.length!==13)
return false
return true
}
this.setISBN=function(){
if(!checkISBN(isbn))
throw Error('Incorrect ISBN number!')
ISBN=isbn
}
this.getISBN=function(){
console.log(`ISBN number is ${ISBN}`)
}
this.setISBN()
}
const book1 = new Book(1122334455667)
book1.ISBN = 987
book1.getISBN() // ISBN number is 1122334455667
在上面的示例中,我们得到了我们期望的结果,即123。但是您可能会认为这行book1.ISBN=987
是什么?
该行在book1
的this
范围中添加了一个新变量。
即
上面的模式非常适合创建私人成员,但它带有成本,即记忆。即,每当我们实例化此Book
类的新对象时,我们就会创建ISBN
和checkISBN
的新副本,将其捆绑在Book
的关闭中。因此,有记忆的浪费。因此,实际需要时,我们只能制作私人属性和方法。
现在让我们来到本文的第二部分:私人静态成员。
在上面的示例中,我们使用了私有方法checkISBN(x)
,您会注意到此方法与单个对象无关。它唯一要做的是检查输入x
并确定它是否正确,因此每当实例化新对象时,就没有任何意义。
因此,我们需要私人静态成员的概念。
静态成员是属于类的成员,而不是对象。即,当定义类时,只有一个成员的单个副本。无论是实例化了多少对象,都只能在存储器中的成员的副本上。
在创建私人静态成员之前,让我们创建一个班级的公共静态成员,这很容易。
const Book = function(isbn){
Book.getLibrary()
}
Book.getLibrary = function(){
console.log('This book belongs to Oxford library.')
}
const book1 = new Book(123) // This book belongs to Oxford library.
要添加一个公共静态成员,我们必须在班级名称空间中添加该成员。
现在,让我们成为一个私人静态成员,这很棘手。
假设我们必须设计一个Book
类,该类将具有一个名为booksCreated
的私有静态属性,该属性最初设置为零,并且每当实例化新书时,此变量都必须增加一个。我们必须确保将其保持私密,因为我们不希望从班级外部进行操纵。
在这里,我们将与IIFE一起使用(立即调用函数表达式)。
const Book = (function(){
let booksCreated = 0 // private static attribute
return function(){
booksCreated++
this.getNumberOfBooks=function(){
return booksCreated
}
}
})()
const b1 = new Book()
const b2 = new Book()
const b3 = new Book()
console.log(b3.getNumberOfBooks()) // 3
console.log(b1.getNumberOfBooks()) // 3