面向对象
JavaScript中的对象定义是:无序属性的集合,其属性值可以包含基本值,对象以及函数。
创建对象的方式:
1,使用工厂模式创建对象:
使用工厂模式创建对象就是创建一个Object对象,再给对象添加属性和方法,工厂模式虽然解决了创建多个相同的对象创建的问题,但是不能识别对象的类型。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>创建对象的几种方式-工厂模式</title> <script> function createPerson(name,age,job){ var obj=new Object(); obj.name=name; obj.age=age; obj.job=job; obj.sayName=function(){ alert("我的名字是"+this.name); } return obj; } var person1=createPerson("猪八戒",28,"医生"); var person2=createPerson("孙悟空",18,"教师"); </script> </head> <body> </body> </html>
2,使用构造器模式创建对象
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>创建对象的几种方式-工厂模式</title> <script> function createPerson(name,age,job){ var obj=new Object(); obj.name=name; obj.age=age; obj.job=job; obj.sayName=function(){ alert("我的名字是"+this.name); } return obj; } var person1=createPerson("猪八戒",28,"医生"); var person2=createPerson("孙悟空",18,"教师"); </script> </head> <body> </body> </html>
从代码可以看出,构造模式和工厂创建的对象的区别是:
没有显示的创建对象
直接将属性和方法赋值给了this对象
没有return语句
创建构造函数的注意事项:构造函数的名称第一个字母应该大写,普通 的函数的名称都是小写,构造本身也是函数,也能够被调用。
使用构造函数创建一个对象必须要使用new操作符,使用new操作符调用构造函数经历的4个步骤:
创建一个新对象
将构造函数的作用域赋值给新对象(this指向了这个对象)
执行构造函数中的代码(为对象添加属性和方法)
返回一个新的对象
将构造函数当作普通函数来使用时候:
在全局作用域中调用一个函数的时候,this指向Global对象(也就是window对象)在调用完后可以使用window对象来调用方法
//将构造函数当作普通函数来使用的时候
Person("沙和尚",38,"服务员"); //添加到window中去了
window.sayName()
将构造函数放在另一个对象中使用的时候:
使用call()方法在某个特定的对象的作用域中调用Person方法,是在o对象中调用的,所以o对象就拥有了所有的属性和方法
var o=new Object();
Person.call(o,"Kirs",25,"Nurse");
o.sayName(); //Kirs的职位是:Nurse
构造函数创建对象的问题:在每使用一次构造函数创建一个对象,都会为该对象创建对应的 属性和方法,每个属性和方法都是对象自己的,同种类型的不同对象的方法都不相同,但是他们所作的工作都是相同的。如下:对象person1的方法和person2的方法都是输出这个对象的name属性值,但是person2和person1的方法是不相等的,像这样每创建一个对象就创建一个函数没有必要。
<!DOCTYPE html> <html> <head> <title> 对象的方法 </title> <script> function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ alert("我是"+this.name); } }; var person1=new Person("猪八戒",12); var person2=new Person("孙悟空",20); person1.sayName(); person2.sayName(); alert(person1.sayName==person2.sayName); //输出false </script> </head> </html>
我们可以把函数放在外面,而在里面将sayName属性的值指向外面的函数,如下:
<!DOCTYPE html> <html> <head> <title> 对象的方法定义 </title> <script> function sayName(){ alert(this.name); } function Person(name,age){ this.name=name; this.age=age; //this.sayName=sayName();这个样是错误的,()是调用方法 this.sayName=sayName; } var person1=new Person("猪八戒",29); var person2=new Person("孙悟空",20); person1.sayName(); person2.sayName(); alert(person2.sayName==person1.sayName); //true </script> </head> </html>
这样,person1和person2就共享了全局作用域中的同一个函数,不用为每一个对象都创建一个方法,但是这样又会出现了新的问题:如果一个构造函数拥有多个方法,那么就需要为在全局作用域中创建多个方法,这样一来我们自定义的引用类型就没有封装性可言了。我们可以使用原型来解决这个问题。
o