因为之前,对js也没深入的学习,只是知道js也是面向对象的语言,也可以创建类,继承之类的概念,可是,从来没整理过这个问题。今天大师兄,提起这个事情,我学习参考了网上大牛写的,粘过来,作为学习笔记学习一下,所以先说一下,有关对象,类的创建。
在js里面,首先明白几个基本概念,比如,js本来没有类,何来的类,以及怎么创建它?由于受java的影响,总分不清楚,function函数和对象的概念。
总结一句,js中一切都是对象,函数也是对象。
1.当你创建一个对象时。。。
一、由一对大括号括起来
var emptyObj = {};
var myObj =
{
'id': 1, //属性名用引号括起来,属性间由逗号隔开
'name': 'myName'
};
//var m = new myObj(); //不支持
像上面的代码,就只是简单的声明一个对象,它只有一份拷贝,你不能像实例化类对象一样对它采用new操作,像上面代码的注释部分。
2.当你创建一大堆对象时。。。
二、用 function 关键字模拟 class
1.工厂方式
function createCar(color, doors, mpg) {
var tempcar = new Object;
tempcar.color = color;
tempcar.doors = doors;
tempcar.mpg = mpg;
tempcar.showColor = function () {
alert(this.color)
};
return tempcar;
}
var car1 = createCar("red", 4, 23);
var car2 = createCar("blue", 3, 25);
car1.showColor(); //outputs "red"
car2.showColor(); //outputs "blue"
缺点也很明显,就是每个对象会重复创建一个showColor(),其实,它们都是同一个,浪费很多资源。
2.构造函数方法
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.showColor = function () {
alert(this.color)
};
}
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.showColor(); //outputs "red"
oCar2.showColor(); //outputs "blue"
3.原型方式
function Car(){
}
Car.prototype.color = "red";
Car.prototype.doors= 4;
Car.prototype.mpg= 23;
Car.prototype.showColor = function(){
alert(this.color);
}
var oCar1 = new Car();
var oCar2 = new Car();
这种方式,虽然解决了上面的问题,可是不足的是,我们无法传入参数,不符合面向对象编程,而且更严重的问题是,里面的属性指向对象时,会造成其他对象都共用问题,例子就不贴了,总之就是还有缺陷。
4.混合的构造函数/原型方式
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike", "Sue");
}
Car.prototype.showColor = function () {
alert(this.color);
};
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers); //outputs "Mike,Sue,Matt"
alert(oCar2.drivers); //outputs "Mike,Sue"
5.动态原型方法
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike", "Sue");
if (typeof Car._initialized == "undefined") {
Car.prototype.showColor = function () {
alert(this.color);
};
Car._initialized = true;
}
}
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers); //outputs "Mike,Sue,Matt"
alert(oCar2.drivers); //outputs "Mike,Sue"
三.类到底是怎么创建的?
2种方式:匿名和直接
var Person = function(name) { // 一个匿名函数, 并将这个函数赋值给一个Person变量, 此时Person成为一个类
this.name = name;
}
function Person(name) { // 直接定义一个叫做Person的函数表示Person类
this.name = name;
}
Person.prototype = { // 定义Person的prototype域
printName: function() { // 定义一个print函数
alert(this.name);
}
}
当你通过函数的方式声明了一个类之后, 你就可以通过new操作符来实例化这个类。这样, 你就可以调用类的成员函数来完成你的逻辑。
var person = new Person("Joe Smith"); // 使用new操作符来新建一个Person的实例, 并赋给变量person
person.printName(); // person就可以看作是一个实例的引用(reference), 所以可以通过这个引用来调用Person类中的成员函数
我们来总结一下创建一个新的类的实例的整个流程和步骤:
1. 通过定义一个函数的方式(匿名或者实名)来声明一个新的类.
2. 如果有必要, 定义这个新的类的prototype域.
3. 使用new操作符紧跟你所定义的函数来创建一个新的类的实例. 一旦JavaScript编译器碰到了new操作符, 它实际上创建了一个空的类实例变量.
4. 将所有这个类的prototype域中的属性与方法复制到这个新的实例中, 并将其成员函数中所有的this指针指向这个新创建的实例.
5. 接下来, 执行紧跟在new操作符后面的那个函数.
6. 当你执行这个函数时, 如果你试图对一个不存在的属性进行赋值, JavaScript编译器将自动为你在这个实例范围内新创建这个属性.
7. 函数执行完毕后, 将这个初始化完成的实例返回.
再深入的为什么能实现class的原理就不深写了,具体想了解可以看原文:http://www.cnblogs.com/tiwlin/archive/2009/08/06/1540161.html