JS创建对象初步理解(工厂,构造,原型)

来源:互联网 发布:温州网络学堂手机版 编辑:程序博客网 时间:2024/04/30 07:20

JavaScript是面向对象的语言,可是又区别于其他的面向对象的语言,相比我学过的C++来说,JS并没有如C++一样对于类的概念,可是JavaScript可以用原型定义对象,原型的属性实例化对象的属性,来完成各种对象构建,原型就是类似于其他面向对象语言中的类。

学习到这里,先不多谈原型的各种性质,先谈原型模式与工厂、构造模式创建对象的区别。

工厂模式是用函数来封装以特定接口创建对象的细节,通过调用函数,来返回一个包含属性和方法的对象。

 function createPerson(name,age,job){

    var o=new Object();
    o.name=name;
    o.age=age;
    o.job=job;
    o.sayName=function(){
    alert(this.name);
     };
    return o;
}
var person1=createPerson("Nicholas",29,"software Engineer");
var person2=createPerson("Greg",27,"Doctor");

虽然是能创建person1、person2等相似对象,可是没有解决对象识别问题,即都是Object。

再看构造函数模式:

function Person(name,age,job){

    this.name=name;
    this.age=age;
    this.job=job;
    this.sayName=function(){
    alert(this.name);
     };
}
var person1=new Person("Nicholas",29,"software Engineer");
var person2=new Person("Greg",27,"Doctor");

这里先说一下构造和工厂的创建区别:

1.构造没用显示创建对象,是在调用构造时new了下下。

2.构造直接将属性和方法赋值给了this对象,由this指向新对象。

3.构造没用return。

(注:构造函数函数名大写开头。)

构造函数解决了工厂模式下的对象识别的问题。


构造函数虽然解决了对象识别问题,可是它会在实例化的时候把所有的方法都给创建一遍。而实际上我们并不需要两个sayName函数,实例时两个同名函数也是不相等的。person1.sayName!=person2.sayName。

有一种解决方法是转移到构造函数外,这样内部属性,外部方法就可以了。但是这样又不能体现封装,并且作用域混乱。所以我们呼唤着另外一个模式的创建,那就是prototype,原型模式。

每一个函数都有一个原型的属性,这个属性是指针,指向一个对象可以包含特定类型的所有实例共享的属性和方法,说到底,prototype也还是构造函数创建实例对象时候的原型对象。重点是,重点是,重点是原型对象的好处是所有对象实例共享它所包含的全部属性和方法,那么就可以不必再在构造函数中定义对象实例的信息了,直接将其加入到原型对象中去。例如上面的问题可以这样去解决。

   function Person(){

 }

  Person.prototype.name = "Nicholas";

  Person.prototype.age = 29;

  Person.prototype.job = "Software Engineer";

  Person.prototype.sayName = function(){

      alert(this.name);

  }; 

 var person1 = new Person();

person1.sayName();//"Nicholas"

var person2 = new Person();

person2.sayName();//"Nicholas"

alert(person1.sayName == person2.sayName);        //true

sayName()方法和所有属性直接加入到了prototype中,构造函数为空,如果直接调用构造来创建新对象,也是一样的。但是原型有所有属性方法实例共享的特点。也就是原型解决了对象识别和方法多实例化的问题。以上几点可以看出工厂、构造、原型三种模式在构建时候的区别。




1 0
原创粉丝点击