面向对象的概念:OOP(面向对象):
全称Object Oriented Programming
不是一种语法,是一种编程思想;js中的面向对象编程,就是创建对象,给对象添加属性和方法。
创建对象:
直接创建:
var obj = { };
这种创建也叫字面量的方式。就是你一眼看到就能知道键的值是多少。
例如:
var obj = {
name:"张三",
age:12,
sex:"男"
}
构造函数方式创建:
var obj = new object();
object是一个系统提供的改造函数,这个构造函数专门用来创建对象的。
给这种对象添加属性和方法的语法:
对象.属性名 = 值;
对象.方法名 = 函数;
例如:
从上面可以看出,每次创建对象都是重复的动作,我们可以用函数来处理。
工厂函数创建对象
概念:定义一个函数,每次调用都能得到一个对象,这种调用就能创建对象的函数,就是工厂函数;
示例:
function createObj(name,age,sex){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
return obj;
}
var obj1 = createObj("张三",12,"男");
console.log(obj1)
var obj2 = createObj("李四",13,"女");
console.log(obj2)
结果:
这种调用就能创建对象的函数,叫做工厂函数。创建出来的每个对象的结构一致。
优点:可以同时创建多个对象;
缺点:创建出来的没有具体的类型(比如是Array和Number),都是object类型的,但我们看到自己的对象只是object,不知道具体是什么类型。
解决方案:自定义构造函数。其实就是自己写一个函数,专门用来new对象。
对于Number、String构造函数来说,他们都是系统内置的函数。
我们自己创建出来的对象之所以都是Object,是因为我们创建对象的时候使用的是new object(); Object也是系统内置的一个构造函数。
例如:
所以我们也要自定义一个构造函数,创建出来的对象也就能看出具体是什么类型的对象。
示例:
function Person(){
name = "李四";
age = 12;
sex = "男";
}
var arr = new Person();
function Dog(){
name = "小白";
sex = "公";
}
var brr = new Dog();
console.log(arr);
console.log(brr);
输出结果:
自定义构造函数:
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
var obj1 = new Person("张三",12,"男");
console.log(obj1)
var obj2 = new Person("李四",13,"女");
console.log(obj2)
构造函数和普通函数不同的地方在于使用new的时候,中间发生了很多看不见的过程:
创建了一个新对象(这个过程是隐形的)
this指向了这个新对象(新对象就有了属性,创建了属性)
执行构造函数,也就是调用了这个函数(给对象添加属性和方法,给属性和方法赋值)
返回这个新对象(返回结果也是隐形的)
使用new构造函数来创建对象的过程称之为实例化。
构造函数注意事项:
构造函数天生就是用来创建对象的,所以必须和new配合使用,否则就不具备创建对象的能力;
构造函数内部不能有return关键字,因为构造函数会自动返回对象。如果返回基本数据类型,和不加效果一样,如果返回复杂数据类型,构造函数就没意义了。
如果new的时候,不需要参数,那么小括号可以省略;
人们通常将构造函数的首字母大写。
一个构造函数中给对象添加了一个方法,然后创建了两个对象,这两个对象都有这个方法,并且这两个方法一模一样,但是这个方法在内存中却是两个空间,这样对于内存空间来说有点浪费,因为两个对象的方法是一样的但是却占了两个空间。
如下示例:
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.say = function(){
console.log('讲话')
}
}
var obj1 = new Person("张三",12,"男");
console.log(obj1)
var obj2 = new Person("李四",13,"女");
console.log(obj2)
console.log(obj1.say === obj2.say);
两个结果相等比较是false表示这是两个空间。
存储对象方法的具体过程如下图:
如果将方法定义在对象外面,可以解决这个问题:
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.say = fn;
}
function fn(){
console.log('讲话')
}
var obj1 = new Person("张三",12,"男");
console.log(obj1)
var obj2 = new Person("李四",13,"女");
console.log(obj2)
console.log(obj1.say === obj2.say);