总结的 Java Script 中定义对象的几种方法,以及各自原理:
1. 基于已有对象来动态扩充其对象和方法
<script type="text/javascript">
//先定义对象,对象里面有属性和方法
var object = new Object();
object.name = "zhangsan";
object.sayName = function(name) {
this.name = name;
alert(this.name);
}
//object对象中既有name属性,也有sayName属性
object.sayName("lisi");
</script>
弊端:对象只有一个,如果再次需要,就要再次创建。
2. 工厂方式创建对象
<script type="text/javascript">
function get() {
alert(this.username + ", " + this.password);
}
function createObject(username, password) {
var object = new Object();
object.username = username;
object.password = password;
object.get = get;
retuen object;
}
var object = createObject("zhansan","123");
var object2 = createObject("lisi", "3432");
object.get();
objcect2.get();
</script>
让一个函数对象被多个对象多使用,不管创建多少对象,使得函数对象只有一份。
3. 构造函数方式创建对象
<script type="text/javascript">
function Person(username, password) {
//在执行第一行代码前,js引擎(浏览器)会为我们生成一个对象 this
this.username = username;
this.password = password;
this.getInfo = function() {
alert(this.username + ", " + this.password);
}
//此处有一个隐藏的return语句,用于将之前生成的对象返回
}
//并且只有使用new的方式生成对象的时候,才会有隐藏的return语句。这点和工厂方法模式有点不一样,工厂方法模式仅仅是在调用方法,并没有new
var person = new Person("sahgnsan", "123");
person.getInfo();
</script>
4. 使用原型prototype的方法定义
<script type="text/javascript">
function Person() {
}
//在函数外对Person扩充,给原型prototype这个属性,给其赋值上一些属性或者方法,这样一来,原型所属的那个对象也就拥有了这些对象和方法
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();
</script>
弊端:
4.1 单纯使用原型方式定义类无法再构造函数中为属性赋初值,不能传参数
4.2 可能会导致程序错误,当给prototype使用赋值的时候,如果赋值的是引用,那么就会导致多个对象指向一个引用,其中一个对象把引用的内容变化了之后,所有的对象都会受到影响。
5. 使用原型+构造函数方式定义对象
<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>
6. 动态原型方式
<script type="text/javascript">
function Person() {
this.name = "zhangsan";
this.password = "123";
if(typeof Person.flag == "undefined"); {
Person.prototype.getInfo = function() {
alert(this.username + ", " + this.password);
}
Person.flag = true;
}
}
var p = new Pserdon();
var p2 = new Pserson();
p.getInfon();
p2.getInfo();
//通过设置一个标志量来达到方法在生成的时候只生成一份的目的,而属性可以设置成动态指定的。
</script>