没有解决对象识别的问题(即怎样知道一个对象的类型)函数
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");
使用构造函数的主要问题,就是每一个方法都要在每一个实例上从新建立一遍。经过把函数定义转移到构造函数外部来解决这个问题this
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"); //把函数定义转移到构造函数外部 function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); } var person1 = new Person("Nicholas", 29, "Software Engineer");
若是对象须要定义不少方法,那么就要定义不少个全局函数,因而咱们这个自定义的引用类型就丝毫没有封装性可言了。prototype
原型对象的好处是可让全部对象实例共享它所包含的属性和方法;
原型模式最大的问题是由其共享的本性致使的:对于那些包含基本值的属性能够经过在实例上添加一个同名属性,能够隐藏原型中的对应属性,可是对于包含引用类型值的属性来讲,问题就很突出了。code
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();
建立自定义类型的最多见方式就是组合使用构造函数模式与原型模式;
构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。对象
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; } Person.prototype = { constructor : Person, sayName : function() { alert(this.name); } } var person1 = new Person("Nicholas",29,"Software Engineer");
经过检查某个应该存在的方法是否有效来决定是否须要初始化原型;
注意:使用动态原型模式时,不能使用对象字面量重写原型。若是在已经建立了实例的状况下重写原型,那么就会切断现有实例与新原型之间的联系;原型
function Person(name, age, job) { this.name = name; this.aghe = age; this.job = job; if(typeof this.sayName !="function") { Person.prototype.sayName = function(){ alert(this.name); }; } } var friend = new Person("Nicholas",29,"Software Engineer");
封装建立对象的代码,而后再返回新建立的对象;
除了使用new操做符并把使用的包装函数叫作构造函数以外,这个模式和工厂模式实际上是如出一辙的io
function Person (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 friend = new Person("Nicholas", 29, "Software Engineer");
稳妥构造函数遵循与寄生构造函数相似的模式,但有两点不一样:
(1)新建立对象的实例方法不引用this;
(2)不使用new操做符调用构造函数。function
function Person(name, age, job) { var o = new Object(); //建立要返回的对象 //能够在这里定义私有变量和函数 o.name = name; o.age = age; o.job= job; //添加函数 o.sayName = function() { alert(name); //注意寄生构造函数中是alert(this.name) }; //返回对象 return o; } //注意寄生构造函数中是var friend = newPerson("Nicholas", 29, "Software Engineer"); var friend = Person("Nicholas", 29, "Software Engineer"); friend.sayName(); //"Nicholas"