参考书籍:JavaScript设计模式
在JavaScript 中创建一个类很容易,首先声明一个函数保存在一个变量里。然后在这个函数(类)的内部通过对 this (函数内部自带的一个变量,用于指向当前这个对象)变量添加属性或者方法来实现对类添加属性或者方法。例如
var Book = function (name, price) {
this.name = name;
this.price = price;i
}
也可以通过在类的原型(类也是对象,所以也有原型 prototype)上添加属性和方法。有2中方式,一种是一 一为原型对象属性赋值,另一种是将一个对象赋值给类的原型对象,但两种不能混用
Book.prototype.displayBook=function(){
//
}
或者
Book.prototype={
displayBook:function(){
//
}
}
这样我们将所需要的属性和方法都封装在抽象的Book类里面了,当使用功能方法时,不能直接使用这个Book类,需要通过 new来实例化(创建)新的对象,使用实例化对象的属性或者方法时,可以通过点语法访问。
面向对象思想你可以想象成一位明星,比如他要在社会中保持一个良好形象,他就会将一些隐私隐藏在心里,然而对于这位明星,他的家人认识他,所以会了解一些关于他的事情。外界的人不认识他,即使外界人通过一些渠道认识他也仅仅是了解一些他暴露出来的事情,不会了解她的隐私。如果想了解更多关于他的事情,可以通过他的家人来了解,但是这位明星内心深处的隐私是永远不会被别人知道的。
对于JavaScript,由于是函数级作用域,声明在
函数内部的变量以及方法
在外界是访问不到的,通过此特性即可创建类的
私有变量和私有方法
。
然而在函数内部通过
this 创建的属性和方法
,在类创建对象时,每个对象自身都拥有一份并且可以在外部访问到。因此通过
this 创建的属性和方法可以看作对象的公有属性和方法
,而且还能访问到类(创建时)或对象自身的私有属性和方法,由于这些方法的权利比较大,所以又看作
特权方法
。在对象创建时通过使用这些特权方法可以初始化实例对象的一些属性,因此在创建对象时调用的特权方法还可以看作是类的
构造器
。如下面的例子
var Book = function (id, name, price) {
//私有属性
var num = 1;
console.log('start this.name value: ' +this.name);
console.log('start this.price value: ' +this.price);
//私有方法
function checkId() { };
//特权方法
this.getName = function () {
return this.name;
};
this.getPrice = function () {
return this.price;
};
this.setName = function () {
this.name = name;
};
this.setPrice = function () {
this.price = price;
};
console.log('middle this.name: ' +this.name);
console.log('middle this.price: ' +this.price);
//对象公有属性
this.id = id;
//对象公有方法
this.copy = function () { };
//构造器
this.setName(name);
this.setPrice(price);
console.log('end this.name: ' +this.name);
console.log('end this.price: ' +this.price);
}
function displayBook() {
var book = new Book(10, 'javascript', 50);
document.getElementById("demo").innerHTML = book.getName();
}
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript</title>
</head>
<body>
book name:<p id="demo">this context will be overwritten when click the button</p>
<button type="button" onclick="displayBook()">display book info</button>
</body>
<script src="./js/a.js"></script>
</html>
通过 new 关键字创建新对象时,由于类外面通过点语法添加的属性和方法没有执行到,所以新创建的对象中无法获取他们,但可以通过类来使用。因此在类外面通过点语法定义的属性以及方法被称为
类的静态公有属性和方法(可以通过类的自身访问)
类通过prototype创建的属性和方法是可以通过this访问到的,被称为
公有属性和方法
。
js
var Book = function (id, name, price,num) {
//this指向Book
//私有属性
var num = 1;
console.log('start this.name value: ' + this.name);
console.log('start this.price value: ' + this.price);
console.log('start this.num value: ' + this.num);
//私有方法
function checkId() { };
//特权方法
this.getName = function () {
return this.name;
};
this.getPrice = function () {
return this.price;
};
this.setName = function () {
this.name = name;
};
this.setPrice = function () {
this.price = price;
};
console.log('middle this.name value: ' + this.name);
console.log('middle this.price value: ' + this.price);
console.log('middle this.num value: ' + this.num);
//对象公有属性
this.id = id;
//对象公有方法
this.copy = function () { };
//构造器
this.setName(name);
this.setPrice(price);
console.log('end this.name value: ' + this.name);
console.log('end this.price value: ' + this.price);
console.log('end this.num value: ' + this.num);
}
//类静态公有属性(对象不能访问)
Book.isChinese = true;
//类静态公有方法(对象不能访问)
Book.resetTime = function () {
console.log('new time');
};
Book.prototype = {
//公有属性
isJSbook: false,
//公有方法
display: function () {
console.log('book display')
}
}
function displayBook() {
//this指向window
var book = new Book(10, 'javascript', 50);
document.getElementById("demo").innerHTML = book.getName();
console.log('book.price: ' + book.price);
console.log('Book.price: ' + Book.price);
console.log('prototype创建的可以直接别访问 ');
console.log('book.isJSbook: ' + book.isJSbook);
console.log('私有属性不能被访问 ');
console.log('book.num: ' + book.num);
console.log('book.isChinese: ' + book.isChinese);
console.log('类的静态公有属性和方法可以通过类的自身访问 ');
console.log('Book.isChinese: ' + Book.isChinese);
Book.resetTime();
console.log('Book.num: ' + Book.num);
}
console
通过 new 关键字创建的对象实质上是对新对象 this 的不断赋值,并将prototype指向类的 prototype所指向的对象,新对象prototype和类的prototype指向的是同一个对象。 而类的构造函数外面通过点语法定义的属性和方法是不会添加到新创建的对象上面的。
类的私有属性以及静态公有属性在新创建的对象里是访问不到的。而类的公有属性在新创建的对象中可以通过点语法访问。
但是类的静态公有属性可以通过类自身访问。
有时候我们经常将类的静态变量通过闭包实现,参考下面link.
https://blog.csdn.net/weixin_44924173/article/details/90904889