javascript面向对象编程

现在在我眼里如果js代码中使用了面向对象,那就高了一个档次,使用面向对象编程可以增加你的代码的灵活性以及可维护性,在后期开发中也可以减少大量的工作,但前提是要正确使用它。

对象是无序属性的集合,其属性可以包括基本值、函数、对象。每个属性都会有一个名字,每个名字映射到一个值上。

那么,如何创建一个对象呢?方法有很多。

1.工厂模式

function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayname = function() {
        console.log("name = " + this.name);
    };
    return o;
}
var person = createPerson("nana", 17);     //注意创建方法
person.sayname();

 这种方法无法知道一个对象的类型。

2.构造函数模式

function Person(name, age, job) {
   this.name = name;
   this.age = age;
   this.job = job;
   this.sayname = function() {
          console.log("name = " + this.name);
   }
}
var person1 = new Person("nana", 17, 'hihi');
person1.sayname();

注意:一般将Person称为构造函数,并且构造函数的名字首字母大写,这是编码规范。

此方法解决了问题,可是不同实例的sayname()函数是不相同的,试一下

alert(person1.sayname == person2.sayname)  //false

这远远不是我们所需要的,那么就想办法解决吧~ 就有了下面方法:

function Person(name, age, job) {
   this.name = name;
   this.age = age;
   this.job = job;
   this.sayName = sayName;
}
function sayName() {
    return console.log(this.name);
}
var person1 = new createPerson("nana", 17, 'hihi');
person1.sayName();

将sayName定义成一个全局方法,这样每个实例共享的都是全局方法sayName()。问题是解决了,可是如果构造函数里有大量的方法,这就造成代码中有大量的全局变量,后果是不堪设想的。因此,又有了其他办法。 

3.原型模式

function Person() {

}
Person.prototype.name = 'nana';
Person.prototype.age = '29';
Person.prototype.sayname = function() {
       console.log("name = " + this.name);
}
var person1 = new Person();
person1.sayname();

 此方法将属性定义在原型上,是解决了上述问题,可是新的问题就又出来了,原型自身存在的问题是当一个实例改变属性值时,所有实例对应的属性值也都跟着改变,还有一个问题是无法初始化属性值。因此,这种方法也是不可以的,那么,综合一下,重头戏来了!!!

4.组合使用构造函数模式和原型模式

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
}
Person.prototype.sayname = function() {
       console.log("name = " + this.name);
}
var person1 = new Person("nana", 17, 'hihi');
person1.sayname();

用构造函数的模式定义属性,用原型模式定义方法和共享属性,结合了两种方法的优点,这种方法是最常用的~~

5.动态原型模式

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    
    //方法
    if(typeof this.sayName != 'function') {
        Person.prototype.sayname = function() {
            console.log("name = " + this.name);
        };
    }
}
var person1 = new Person("nana", 17, 'hihi');
person1.sayname();

动态原型方法可以通过检查方法是否有效,决定初始化的原型。这种方法堪称为完美,但是不能使用面向字面量重写原型,这样会切断现有实例与新原型之间的联系。

6.寄生构造函数模式

function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayname = function() {
        console.log("name = " + this.name);
    };
    return o;
}
var person = new createPerson("nana", 17);     //注意创建方法
person.sayname();

此方法可以和工厂模式对比一下,创建实例方法与构造函数相同,其余与工厂模式相同。如果前面方法都不适用可以考虑一下这种方法,但是这种方法构造函数返回的对象与实例没有关系,也不能依赖instanceof判断对象类型,因此,如果可以使用其他模式这种方法建议还是不要使用。

7.稳妥构造函数模式

function Person(name, age, job) {
    var o = new Object();
    //定义一些私有变量和函数
    o.sayname = function() {
        console.log("name = " + name); //定义的私有变量等只能通过sayname访问
    };
    return o;
}
var person1 = Person("nana", 17, "lili");
person1.sayname();

 这种方法适合用于在安全的环境下,因为它不使用new调用构造函数,也不使用this引用实例方法。若想访问其属性,只能通过sayname方法来访问其内部私有属性。

其实大二的时候上过面向对象编程的课,但是看了js创建对象的模式还是有点蒙,今天又整理了一遍突然发现思路比较清晰了~如果你还是不懂的话,那就去写代码吧~~~~~写完代码后就会发现也不过如此嘛~~

嘿嘿~如果有什么不对的地方求指教~~~

原文地址:https://www.cnblogs.com/nalixueblog/p/4519521.html