创建对象:
var person = new Obejct(); person.name = 'sun'; person.sayName = function(){ alert(this.name); //this.name将被解析为person.name }
对象字面量语法:但是当需要创建多个对象时,会产生大量重复的代码:
var person = { name : 'sun', age : 11, sayName : function(){ alert(this.name); } }
工厂模式:用函数来封装特定对象的创建细节
function createPerson(name, age){ var p = new Object(); p.name = name; p.age = age; p.sayName = function(){ alert(this.name); }; return p; } var person1 = createPerson("sun", 13);
问题:没有解决对象识别问题(不能知道对象的类型)。
构造函数模式:
function Person(name, age){ this.name = name; this.age = age; this.sayName = function(){ alert(this.name); }; } var person1 = new Person("sun",12); alert(person1.constructor);
1:不再显示的创建对象
2:直接将属性和方法赋值给this对象
3:没有return语句
构造函数模式的问题:每个方法都要在每个实例上春心创建一遍。
解决这个问题的简单方法——把函数的定义转移到构造函数外部。
下面例子中所有对象实例将共享一个全局的函数,函数sayName被调用时,通过this绑定执行环境中的Person对象
function Person(name){ this.name = name; this.sayName = sayName;//指针 } function sayName(){ alert(this.name); }
新问题:如果需要定义多个方法,就要定义多个全局函数。且此方法破坏了新对象类型的封装性。
原型模式:
每个函数都有一个原型属性:prototype,它是一个指针,指向一个对象。这个对象的用途是:包含特定类型的所有实例共享的属性和方法。
使用原型对象的好处:让所有对象实例共享它所包含的属性和方法。
function Person(){} Person.prototype.name = 'sun'; Person.prototype.age = 18; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); alert(person1.name); //sun var person2 = new Person(); alert(person2.name); //sun alert(person1.sayName == person2.sayName); //true,同一个方法
每创建一个函数,就会同时创建他的prototype对象,这个对象也会自动拥有一个constructor属性指向函数本身。
更简单的原型模式: 原型+对象字面量
function Person(){} Person.prototype = { //constructor : Person, name : 'sun', age : 15, job : '...', sayName : function(){ alert(this.name); } };
注意:此时constructor属性不在指向Person。
这种语法的本质:完全重写了默认的prototype对象,这个对象也会自动获得一个constructor属性,这个constructor指向Object构造函数,
如果constructor真的很重要,可以像上面注释掉的那样,显式的生命constructor
但这个constructor是可枚举的,默认的constructor是不可枚举的,因此可以使用下列方法设置。
(该方式仅适用于兼容ECMAScript5的浏览器)
Object.defineProperty(Person.prototype, "constructor", { enumerable : false ; //不可枚举 value : Person });
原型模式的问题:prototype中的属性值如果是引用类型,会被所有对象实例共享。
组合使用构造函数模式和原型模式:
构造函数模式用于定义实例的属性,原型模式用于定义方法和共享的属性。
function Person(name, age){ this.name = name; this.age = age; this.friends = ["sun","cheng"]; } Person.prototype = { constructor : Person, sayName : function(){ alert(this.name); } }