ECMAScript中没有类的概念,因此它的对象也基于类的对象有所不同。
ECMA-262定义对象为:“无序属性的集合,属性可以包含基本值、对象或者函数”。
可以把它想象成一个散列表 无非就是一组名值对,值可以是属性或者方法。
面向对象程序设计中常用的概念对象,方法、属性、类、分装、聚合、继承、多态.
创建对象
//创建一个Object实例 var person = new Object(); person.name = "Alice"; person.age = 23; person.sayname = function(){ alert(this.name); }; //用字面量创建 var person = { name: "Alice", age : 23, sayName:function(){ alert(this.name); } };
工厂模式抽象了具体创建对象的过程,ECMAScript没有类的接口,开发人员发明了一种函数,用函数类分装特定接口创建对象的细节。
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; }这个函数能根据接受的参数来构建一个包含所有表信息的person对象,可以无数次的调用这个函数,而且每次都会返回一个包含三个属性一个方法的对象。工厂模式解决了相似创建的问题但没有解决对象识别的问题。所以出现了另一种模式
function Person(name, age, job){ //按照惯例构造函数始终是以大写字母开头 this.name = name; this.age = age; this.sayName = fuction(){ alert(this.name); }; } var person1 = new Person("alice", 34, "doctor"); var person2 = new Person("bob", 24, "actor");
alert(person1 instanceof Object);//true alert(person2 instanceof Person);//true
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = new function("alert(this.name)"); }
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); }这样做解决了两个实例中不同的函数做同样的事情,但是问题又来了; 在全局作用域中的某个函数实际上只能被某个对象调用,更让人无法接受的是如果需要定义很多方法,那么就要定义很多全局函数,然而自定义的引用类型就没有什么封装性可言了,好在这些问题可以使用原型模式来解决。
function Person(){ } Person.prototype.name = "alice"; Person.prototype.age = "alice"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); Person1.sayName(); var person2 = new Person(); Person2.lsayName(); alert(person1.sayName == person2.sayName); //true
alert(Person.prototype.isPrototypeOf(person1)); //true alert(Person.prototype.isPrototypeOf(person2)); //true
delete person1.name; hasOwnProperty(),用这个方法可以检测一个属性是否存在于实例中。 person1.hasOwnProperty("name");
function Person(){ } Person.prototype.name = "alice"; Person.prototype.age = "alice"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.hasOwnProperty("name");//false alert("name" in person1); //true //通过hasOwnProperty和in操作符就能够确定属性在实例中还是在原型中 function hasPrototypeProperty(Object, name){ return !Object.hasOwnProperty(name) && (name in Object); }
function Person(){ }; Person.prototype = { name: "Aclie", age : 23, sayName:function(){ alert(this.name); } };
function Person(){ }; Person.prototype = { conatructor : Person, name: "Aclie", age : 23, sayName:function(){ alert(this.name); } };
function Person(){ }; Person.prototype = { conatructor : Person, name: "Aclie", age : 23, firends :["alex", "penny"], sayName:function(){ alert(this.name); } }; var person1 = new Person(); var person2 = new Person(); person1.firents.push("vam"); alert(person1.firends); //"alex", "penny",""vam alert(person2.firends); //"alex", "penny",""vam
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.firends = ["tiffniy", "cooper"]; } Person.prototype = { constructor : Person, sayName : function(){ alert(this.name); } } var person1 = new Person("Alcie", 23, "font-end engineer"); var person2 = new Person("Bob", 34, "Doctor"); person1.firends.push("van"); alert(person1.firends); alert(person2.firends); alert(person1.firends === person2.firends ); //false alert(person1.sayName=== person2.sayName ); //true
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.firends = ["tiffniy", "cooper"]; if(typeof this.sayName != "function"){ //检查一个即可 //里面可以定义若干个 this.prototype.sayName = function(){ alert(this.name); } } }
function Person(name, age, job){ var o = new Object(); //添加私有变量和函数 //添加方法 o.sayName = function(){ alert(name); } //返回对象 return o; }