两种开发模式:函数式(过程化),面向对象(OOP)。面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,ECMAScript没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。
为了解决多个类似对象声明的问题,我们可以使用一种叫做工厂模式的方法,这种方法就是为了解决实例化对象产生大量重复的问题。工厂模式的识别问题(无法搞清他们是哪个对象的实例)
function createObject(name, age) { //集中实例化的函数 varobj = new Object(); obj.name= name; obj.age= age; obj.run= function () { return this.name + this.age + 'Running...'; }; returnobj; } var obj1 = createObject('Jess', 25); //第一个实例 var obj2 = createObject('Jack', 28); //第二个实例 alert(obj1.run()); alert(obj2.run()); //保持独立
ECMAScript中可以采用构造函数(构造方法)可用来创建特定的对象。类型于Object对象。
function Man(name, age) { //构造函数模式 this.name= name; this.age= age; this.run= function () { return this.name + this.age + 'Running...'; }; } var obj1 = new Man('Jess', 25); //new Man()即可 var obj2 = new Man('Jack', 28); alert(obj1.run()); alert(obj1 instanceof Man); //很清晰的识别他从属于Man
使用了构造函数的方法,和使用工厂模式的方法他们不同之处如下:
1.构造函数方法没有显示的创建对象(newObject());
2.直接将属性和方法赋值给this对象;
3.没有renturn语句。
构造函数的方法有一些规范:1.函数名和实例化构造名相同且大写,(非强制,有助于区分构造函数和普通函数);2.通过构造函数创建对象,必须使用new运算符。 既然通过构造函数可以创建对象,对象执行的过程如下:1.当使用了构造函数,并且new 构造函数(),那么就后台执行了new Object();2.将构造函数的作用域给新对象,(即newObject()创建出的对象),而函数体内的this就代表newObject()出来的对象。3.执行构造函数内的代码;4.返回新对象(后台直接返回)。关于this的使用,this其实就是代表当前作用域对象的引用。如果在全局范围this就代表window对象,如果在构造函数体内,就代表当前的构造函数所声明的对象。构造函数和普通函数的唯一区别,就是他们调用的方式不同。只不过,构造函数也是函数,必须用new运算符来调用,否则就是普通函数。var foo = 2; alert(this.foo); //全局,代表window var foo = new Man('Jess', 25); //构造模式调用 alert(foo.run()); Man('Jerry', 20); //普通模式调用,无效 var o = new Object(); Man.call(o, 'Jack',28) //对象冒充调用 alert(o.run()); //探讨构造函数内部的方法(或函数)的问题 var obj1 = new Man('Lee', 100); //传递一致 var obj2 = new Man('Lee', 100); //同上 alert(obj1.name == obj2.name); //true,属性的值相等 alert(obj1.run == obj2.run); //false,方法也是一种引用地址 alert(obj1.run() == obj2.run()); //true,方法的值相等,传参一致 /* 可以把构造函数里的方法(或函数)用new Function()方法来代替,得到一样的效果,更加证明,他们最终判断的是引用地址,唯一性。 */ function Man(name, age) { //new Function()唯一性 this.name= name; this.age= age; this.run= new Function("return this.name + this.age + 'Running...'"); }//我们可以通过构造函数外面绑定同一个函数的方法来保证引用地址的一致性 function Man(name, age) { this.name= name; this.age= age; this.run= run; } function run() { //通过外面调用,保证引用地址一致 returnthis.name + this.age + 'Running...'; } /* 虽然使用了全局的函数run()来解决了保证引用地址一致的问题,但全局中的this在对象调用的时候是Man本身,而当作普通函数调用的时候,this又代表window。 */