前言
面向对象编程是将需求抽象成一个对象,针对对象分析其特征(属性)和动作(方法)。这个对象我们称之为类。面向对象编程思想其中一个特点就是封装,就是把需要的功能放在一个对象里。但是JavaScript这种解释性的弱类型语言没有经典强类型语言中通过关键字class来实现类的封装,JavaScript都是通过一些特性模仿实现的,这也让JavaScript有更高的灵活性。
封装
为类添加属性和方法的两种方式
- 在函数(类)的内部通过this添加属性和方法
//创建类,通过this实现对类添加属性和方法
var Book = function (id, bookname, price) {
this.id = id;
this.bookname = bookname;
this.price = price;
}
- 通过在类的原型上添加属性和方法
1)为原型对象属性赋值
Book.prototype.display = function () {
}
2)将一个对象赋值给类的原型对象
Book.prototype = {
display :function () {
}
}
这样就将需要的方法和属性封装在抽象的Book类中,当使用功能方法时,不能直接使用Book类,而需要new关键字来实例化(创建)新的对象。
注意:通过this添加的属性和方法是在当前对象上添加的,而通过JavaScript是一种基于原型prototype的语言,所以每创建一个对象时,都有一个原型prototype用于指向其继承的属性、方法。这样通过prototype继承的方法并不是对象自身的。所以每次通过类创建一个新对象时,this指向的属性和方法都会得到相应的创建,但是通过prototype继承的属性和方法是每个对象通过prototype访问到,这些属性和方法不会再次创建。
通过this创建的属性是公有属性,通过this创建的方法是特权方法,在创建对象时调用特权方法可以看做是类的构造器。通过new关键字创建新对象时,由于类外面通过点语法添加的属性和方法没有执行到,所以新创建的对象中无法获取到,而prototype创建的属性或方法可以访问到,所以prototype对象中的属性和方法称为共有属性和方法。
如下:
var Book = function (id, name, price) {
}
Book.isChinese = true;
Book.prototype = {
isJsBook : false,
display :function () {}
}
var b = new Book(11,'ava', 30);
console.log(b.isJsBook); //false
console.log(b.id); // 11
console.log(b.idChinese); //undefined
console.log(Book.isChinese);// true
闭包实现
闭包是有权访问另一个函数作用域中变量的函数,即在一个函数内部创建另一个函数。将闭包作为创建对象的构造函数。
//利用闭包实现
var Book =(function () {
var bookNum = 0;
function checkBook(name) {}
function book(newId,newName,newPrice) {
var name,price;
function checkId() {}
this.getName = function(){};
this.getPrice = function () {};
this.setName = function () {};
this.setPrice = function () {};
this.id = newId;
this.copy = function () {};
bookNum++
if(bookNum>100){
throw new Error('100本书');
}
this.setName(name);
this.setName(price);
}
_book.prototype = {
isJsBook :false,
display:function () {}
};
return _book;
})();
由于在创建对象上这种写法容易忘记使用new而犯错误,所以可以使用安全模式创建对象,也就是在创建对象过程中用instanceof判断this是否是当前这个对象。
if(this instanceof Book){
...
}else{
return new Book()
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。