js类的基本含义
我们知道,在js
中,是没有类的概念的。类的所有实例对象都从同一个原型对象上继承属性,因此,原型对象
是类的核心。
类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。———百度百科
早期的javascript
需求都很简单,基本都是写成函数的,然后是面向过程的写法,后来慢慢的引入面向对象开发思想,再后来就慢慢写成 类
。
在js
中,写成类的本质基本都是 构造函数+原型
。下面,就讨论一下js类的几种写法:
构造函数 法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| /**
* Person类:定义一个人,有name属性和getName方法
*/
<script>
function Person(name){
this.name = name;
this.getName = function(){
return this.name;
}
}
var p1 = new Person("trigkit4");
var p2 = new Person("mike");
console.log(p1 instanceof Person);
console.log(p2 instanceof Person);
</script>
|
由上面控制台输出结果可知,p1和p2的确是类Person
的实例对象。instanceof
操作符左边是待检测类的对象,右边是定义类的构造函数。这里,instanceof
用来检测对象p1
是否属于Person
类。
这种方式的优点是:我们可以根据参数来构造不同的对象实例 ,缺点是每次构造实例对象时都会生成getName
方法,造成了内存的浪费 。
我们可以用一个外部函数来代替类方法,达到了每个对象共享同一个方法。改写后的类如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| //外部函数
<script>
function getName() {
return this.name;
}
function Person(name){
this.name = name;
this.getName = getName;
}
</script>
|
原型方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <script>
function Person(){};
Person.prototype.name = "trigkit4";
Person.prototype.getName = function(){
return " I'm " + this.name;
}
var p1 = new Person();
var p2 = new Person();
console.log(p1.name);
console.log(p2.getName());
</script>
|
原型方式
的缺点就是不能通过参数来构造对象实例 (一般每个对象的属性是不相同的) ,优点是所有对象实例都共享getName
方法(相对于构造函数方式),没有造成内存浪费 。
构造函数+原型方式
取前面两种的优点:
a、用构造函数来定义类属性(字段)。
b、用原型方式来定义类的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script>
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
return " I'm " + this.name;
}
</script>
|
这样,我们就既可以构造不同属性的对象,也可以让对象实例共享方法,不会造成内存的浪费。
为了让js
代码风格更紧凑,我们让prototype
方法代码移到function Person
的大括号内。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <script>
function Person(name){
this.name = name;
Person.prototype.getName = function(){
return this.name;
}
}
var p1 = new Person('trigkit4');
console.log(p1.getName());
</script>
|
在这里,我们需要知道的几种定义类的方法,除了上面的构造函数外,还有:
Object.create()
方法
用这个方法,"类"
就是一个对象,而不是函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var Person = {
name : "trigkit4",
age : 21,
run: function(){
alert("I like running");
}
}
|
然后,直接用Object.create()
生成实例,不需要用到new。
1 2 3 4 5 6
| var p1 = Object.create(Person);
alert(p1.age);
p1.run();
|
这种方法比”构造函数法
“简单,但是不能实现私有属性和私有方法,实例对象之间也不能共享数据,对”类”的模拟不够全面。
createNew()
方法
这种方法不需要用到this和prototype
,其做法是用对象来模拟一个类,然后在类里面定义一个构造函数createNew()
,
然后在createNew()里面定义实例对象,把这个实例对象作为返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <script>
var Person = {
createNew : function () {
var person = {};
person.name = "trigkit4";
person.run = function(){
alert("I like running");
};
return person;
}
}
</script>
|
使用的时候,调用createNew()
方法,就可以得到实例对象。
1 2 3 4
| var p1 = Person.createNew();
p1.run();
|
这种写法其实和对象字面量的写法是很类似的,只不过一个是逗号分隔,一个是分号分隔。