转自: http://www.cnblogs.com/mengdd/p/3697255.html
JavaScript 中没有类的概念,只有对象。
在 JavaScript 中定义对象可以采用以下几种方式:
1. 基于已有对象扩充其属性和方法
2. 工厂方式
3. 构造函数方式
4. 原型 ("prototype") 方式
5. 动态原型方式
- <script type="text/javascript">
- var object = new Object();
- object.name = "zhangsan";
- object.sayName = function(name)
- {
- this.name = name;
- alert(this.name);
- }
- object.sayName("lisi");
- </script>
这种方式的弊端:这种对象的可复用性不强,如果需要使用多个对象,还需要重新扩展其属性和方法。
- function createObject()
- {
- var object = new Object();
- object.username = "zhangsan";
- object.password = "123";
- object.get = function()
- {
- alert(this.username + ", " + this.password);
- }
- return object;
- }
- var object1 = createObject();
- var object2 = createObject();
- object1.get();
改进一:采用带参数的构造方法:
- function createObject(username, password)
- {
- var object = new Object();
- object.username = username;
- object.password = password;
- object.get = function()
- {
- alert(this.username + ", " + this.password);
- }
- return object;
- }
- var object1 = createObject("zhangsan", "123");
- object1.get();
改进二:让多个对象共享函数对象
这样,不用每个对象都生成一个函数对象。
- function get()
- {
- alert(this.username + ", " + this.password);
- }
- //函数对象只有一份
- function createObject(username, password)
- {
- var object = new Object();
- object.username = username;
- object.password = password;
- object.get = get; //每一个对象的函数对象都指向同一个函数对象
- return object;
- }
- var object = createObject("zhangsan", "123");
- var object2 = createObject("lisi", "456");
- object.get();
- object2.get();
优点:让一个函数对象被多个对象所共享,而不是每一个对象拥有一个函数对象。
缺点:对象和它的方法定义分开了,可能会造成误解和误用。
改进版:加上参数:
- function Person(username, password)
- {
- this.username = username;
- this.password = password;
- this.getInfo = function()
- {
- alert(this.username + ", " + this.password);
- }
- }
- var person = new Person("zhangsan", "123");
- person.getInfo();
例子:
- function Person()
- {
- }
- Person.prototype.username = "zhangsan";
- Person.prototype.password = "123";
- Person.prototype.getInfo = function()
- {
- alert(this.username + ", " + this.password);
- }
- var person = new Person();
- var person2 = new Person();
- person.username = "lisi";
- person.getInfo();
- person2.getInfo();
使用原型存在的缺点:
1. 不能传参数;
2. 有可能会导致程序错误。
如果使用原型方式来定义对象,那么生成的所有对象会共享原型中的属性,这样一个对象改变了该属性也会反映到其他对象当中。
单纯使用原型方式定义对象无法在构造函数中为属性赋初值,只能在对象生成后再去改变属性值。
比如,username 改为数组后:
- function Person()
- {
- }
- Person.prototype.username = new Array();
- Person.prototype.password = "123";
- Person.prototype.getInfo = function()
- {
- alert(this.username + ", " + this.password);
- }
- var person = new Person();
- var person2 = new Person();
- person.username.push("zhangsan");
- person.username.push("lisi");
- person.password = "456";
- person.getInfo(); //输出:zhangsan,lisi, 456
- person2.getInfo(); //输出:zhangsan,lisi, 123
- //虽然没有对person2对象进行修改,但是它的name和person是一样的,即为zhangsan,lisi
这是因为使用原型方式,person 和 person2 指向的是同一个原型,即对应了同样的属性对象。
对于引用类型 (比如数组),两个对象指向了同一个引用,所以对一个所做的更改会影响另一个。
而对于字符串 (字面常量值),重新赋值之后就指向了另一个引用,所以二者的修改互不影响。
对原型方式的改进:
使用原型 + 构造函数方式来定义对象,对象之间的属性互不干扰,各个对象间共享同一个方法。
- <script type="text/javascript">
- //使用原型+构造函数方式来定义对象
- function Person()
- {
- this.username = new Array();
- this.password = "123";
- }
- Person.prototype.getInfo = function()
- {
- alert(this.username + ", " + this.password);
- }
- var p = new Person();
- var p2 = new Person();
- p.username.push("zhangsan");
- p2.username.push("lisi");
- p.getInfo();
- p2.getInfo();
- </script>
在构造函数中通过标志量让所有对象共享一个方法,而每个对象拥有自己的属性。
- <script type="text/javascript">
- function Person()
- {
- this.username = "zhangsan";
- this.password = "123";
- if(typeof Person.flag == "undefined")
- {
- //此块代码应该只在第一次调用的时候执行
- alert("invoked");
- Person.prototype.getInfo = function()
- {
- //这个方法定义在原型中,会被每一个对象所共同拥有
- alert(this.username + ", " + this.password);
- }
- Person.flag = true;//第一次定义完之后,之后的对象就不需要再进来这块代码了
- }
- }
- var p = new Person();
- var p2 = new Person();
- p.getInfo();
- p2.getInfo();
- </script>
来源: http://www.bubuko.com/infodetail-1978796.html