面向对象编程就是将你的需求抽象成一个对象,而后针对这个对象分析器特征(属性)与动做(方法)。这个对象咱们称之为类。 面向对象编程思想其中有一个特色就是封装。javascript
在ES5中建立一个类很容易,首先声明一个函数保存在一个变量里(变量名首字母大写),在这个函数(类)的内部经过this(函数内部自带的一个变量,用于指向当前这个对象)变量添加属性或者方法来实现对类添加属性或者方法java
var Book = function(id,bookName,price){编程
this.id = id;安全
this.bookName = this.bookName;闭包
this.price = price;函数
}this
也能够经过在类(类也是一个对象,因此也有原型)的原型上添加属性和方法。spa
1.一一为原型对象属性赋值prototype
Book.prototype.display = function(){};对象
2.将一个对象赋值给类的原型对象
Book.prototype = {
display: fnction(){}
}
var book = new Book(1,'javascript',55);
console.log(bookName) //javascript
经过this添加的属性和方法 与 在prototype中添加的属性和方法有什么区别?
经过this添加的属性和方法是在当前对象上的,然而Javascript是一种基于原型prototype的语言,因此每建立一个对象时(在javascript中函数也是一种对象),它都有一个原型prototype用于指向其继承的属性和方法。这样经过prototype继承的方法并非对象自身的,因此在使用这些方法时,须要经过prototype一级一级的查找来获得,这样你就会发现经过this定义的属性或者方法是该对象自身拥有的,因此每建立一个新的对象时,this指向的属性和方法都会获得相应的建立,而经过prototype建立的属性或者方法是每一个对象经过prototype访问到,因此经过类建立一个新对象时这些属性和方法不会再次建立。
原型对象prototype
constructor是一个属性,当建立一个函数或者对象时都会为其建立一个原型对象prototype,在prototype对象中又会像函数中建立this同样建立constructor属性,那么constructor属性指向的就是拥有整个原型对象的函数或者对象。
属性与方法的封装
私有属性,私有方法,共有属性,共有方法,保护方法等等
因为Javascript的函数级做用域,声明在函数北部的变量以及方法在外界是访问不到的,经过此特性建立类的私有变量以及私有方法。
在函数内部经过this建立的属性和方法,在类建立对象时,每一个对象自身都拥有一份而且外面能够访问到,经过this建立的属性可看做时对象共有属性和对象共有方法。(这个还能访问类或对象自身的私有属性和私有方法) ==特权方法
在对象建立时经过使用这些特权方法,能够初始化实例对象一些属性,所以在建立对象时调用的特权方法还能够看做是类的构造器。
// 私有属性与私有方法, 特权方法 对象共有属性和对象共有方法 构造器
var Book = function(id,name,price){
//私有属性
var num = 1;
//私有方法
function checkId(){}
//特权方法
this.getName = function(){}
this.getPrice = function(){}
this.setName = function(){}
this.setPrice = function(){}
//对象的共有属性
this.id = id
//对象共有方法
this.copy = function(){}
//构造器
this.setName(name);
this.setPrice(price);
}
经过javascript函数做用域的特征来实现函数内部建立外界就访问不到的私有化变量与私有化对象。经过new关键字实例化对象时,因为对类执行一次,全部类的内部this上定义的属性和方法天然能够复制到新建立的对象上,成为对象公有化的属性和方法,而其中一些方法能够访问到类的私有属性和方法。咱们在经过new 关键字实例化对象时,执行了一遍类的函数,因此经过特权方法自让能够初始化对象的一些属性了。
问题1. 在类的外部经过点语法定义的属性和方法以及在外部经过prptotype定义的属性和方法有什么做用?
经过new关键字建立新对象时,因为类外面经过点语法添加的属性和方法没有执行到,全部新建立的对象中没法获取他们,可是能够经过类来使用。所以在类外面经过点语法定义的属性和方法被称为类的静态共有属性和类的静态方法。而经过prototype建立的属性或者方法在类实例的对象中是能够经过this访问到的,因此咱们将prototype对象中的属性和方法称之为共有属性和共有方法。
//类静态共有方法(对象不能访问)
Book.isChinese = true;
//类静态共有方法(对象不能访问)
Book.resetTime = function(){}
Book.portotype = {
//公有属性
isJSBook: false,
//公有方法
display: function(){}
}
经过new关键字建立的对象实质上是对新对象this的不断赋值,并将prototype指向类的prototype所致的对象那个,而类的构造函数外面经过点语法添加定义的属性方法是不会添加到新建立的对象上去的。所以要想在新建立的对象中使用isChinese就得经过Book类使用而不是经过this。而类的原型prototype上定义的属性在新对象里能够之恶极使用,这是由于新对象prototype和类执行的是同一个队象。
var b = new Book(11,'javascript',50);
console.log(b.num) // undefined
console.log(b.isJSBook) //true
console.log(b.id) //11
console.log(b.isChinese) //undefined
类的静态公友属性能够经过类的自身访问
console.log(Book.isChinese) //true
Book.resetTime() //
闭包实现
闭包是有权访问另外一个函数做用域中变量的函数,即在一个函数内部建立另外一个函数。
var Book = (function(){
//静态私有变量
var bookNum = 0;
//静态私有方法
function checkBook(){
}
//返回构造函数
function _book(newId,newName,newPrice){
//私有变量
var name = newName;
var price = newPrice;
//私有方法
function checkId(id){}
//特权方法
this.getName = function(){}
this.getPrice = function(){}
this.setName = function(){
console.log(name)
}
this.setPrice = function(){}
//公有属性
this.id = newId;
//公有方法
this.copy = function(){}
bookNum++
if(bookNum>2){
throw new Error('仅剩一本')
}
this.setName(name)
this.setPrice(price)
}
//构造原型
_book.prototype = {
isJSBook: false,
display: function(){}
}
//返回类
return _book
})()
var b = new Book(1,"javascript",11)
console.log(b.isJSBook)
//建立对象的安全模式
new关键字的做用可看做是对当前的对象的this不停的赋值。若是没有new,this的指向就会指向全局做用域。
var Book = function(id,name){
//判断执行过程当中this是不是当前这个对象(这里说明是用new建立的)
if(this instanceof Book){
this.id = id
this.name = name
//不然从新建立对象
}esle{
return new Book(id,name)
}
}
var book = Book(1,"javascript")
每一个类都有三个部分
1. 构造函数内的,这是供实例化对象复制用的,
2.构造函数外的,直接经过点语法添加的,这是供类使用的,实例化对象是访问不到的。
3.是类的原型中的,实例化对象能够经过其原型链间接的访问到,也是为供全部实例化对象所共用。