首页 > 代码库 > JS面向对象笔记

JS面向对象笔记

1、工厂模式

function CreatePerson(name,age,job){

    var o = new Object();

    o.name = name;
    o.age  = age;
    o.job  = job;

    o.showName = function(){
        alert(this.name);
    } 

    return o;
}

var person1 = CreatePerson(‘王五‘,‘25‘,‘Coder‘);

可以按照上述方式批量生成包含所有必要信息的CreatePerson对象 并且可以反复调用

缺点是 无法解决对象识别的问题

 

2、构造函数模式

// 构造函数模式
function CreatePerson(name,age,job){
    this.name = name;
    this.age  = age;
    this.job  = job;
    this.showName = function(){
        alert(this.name);
    }     
}

var person1 = new CreatePerson(‘王五‘,‘25‘,‘Coder‘);
var person2 = new CreatePerson(‘王五‘,‘25‘,‘Coder‘);

此时 有如下几个优点

  1. 没有工厂模式下的显式的创建对象
  2. 直接将属性和方法赋给了this对象
  3. 并且没有return语句等缺点 

缺点

  1. 必须用new操作符来创建一个新的实例
  2. 方法不公用

pesron1和pesron2是两个不同的实例 指向不同地址 所以不相等

console.log( person1 == person2); //false

但是两个对象都拥有constructor属性 并且该属性指向CreatePerson

1 console.log( person1.constructor == CreatePerson);            //ture
2 console.log( person1.constructor == person2.constructor);    //true

本来constructor属性是用来标识对象类型的,但是现在有更多的标识对象类型的方法 instanceof

1 console.log( person1 instanceof Object );             //true
2 console.log( person1 instanceof CreatePerson );    //true    

方法不公用

1 console.log( person1.showName == person2.showName);     //false

 

3、原型模式

每一个函数都有prototype原型属性 这个属性是一个指针 指向一个对象 可以用这个原型来实现方法的公用

 1 // 原型模式
 2 function CreatePerson(name,age,job){
 3     this.name = name;
 4     this.age  = age;
 5     this.job  = job;
 6 }
 7 
 8 CreatePerson.prototype.showName = function(){
 9         alert(this.name);
10 }     
11 
12 var person1 = new CreatePerson(‘王五‘,‘25‘,‘Coder‘);
13 var person2 = new CreatePerson(‘王五‘,‘25‘,‘Coder‘);

此时的方法公用

1 console.log(person1.showName == person2.showName);  //true

 

未完待续。。。。。。。。。。。。。。。

 

 

新建一个名为Person的构造函数

function Person(name,sex){
        this.name = name;
        this.sex  = sex;

    }
    Person.prototype.showName = function(){
        console.log(this.name);
    }
    Person.prototype.showSex = function(){
        console.log(this.sex);
    }

    // 新建一个Person构造函数的实例
    var person1 = new Person(‘张三‘,‘男‘);
    person1.showName();        //张三
    person1.showSex();        //

再新建一个名为Worker的构造函数

通过call()或者apply()来实现继承父级的属性

常见的错误继承方法

function Worker(name,sex,job){
        //构造函数伪装 将Worker构造函数中this传到Person中
        //继承父级的属性  call来改变作用域 也可以使用apply
        //
        //第一种call  必须要将第二个参数全部列举出来
        Person.call(this,name,sex);

        //第二种apply    参数为数组
        // Person.apply(this,[name,sex]);
        
        this.job = job;

    }

    // 原型链 继承父级的原型方法
    
    // 第一种  浅复制 指向同一地址 对Worker的方法会影响到父级Person  不推荐使用 
    Worker.prototype = Person.prototype;

    Worker.prototype.showJob = function(){
        console.log(this.job);
    }

    var worker1 = new Worker(‘李四‘,‘女‘,‘UI设计师‘);
    worker1.showName();    //李四
    worker1.showSex();     //
    worker1.showJob();  //UI设计师

此时

// 问题出在父级也拥有子级的showJob方法
    console.log(Person.prototype);
    //Object {
        //showJob: ()
        //showName: ()
        //showSex: ()
        //__proto__: Object
    //}

这是由于前复制

Worker.prototype = Person.prototype;

 父级和子级指向同一对象的地址 对子级的修改同样会影响到父级 为了避免这样的情况得new一个新对象来开辟新的地址来存放对象

// 第二种 寄生构造函数模式
    Worker.prototype = new Person();
    // 或者 通过循环的方式
    for( var i in Person.prototype){
        Worker.prototype[i] = Person.prototype[i];
    }

此时 

console.log(Person.prototype);

没有showJob的方法

 

instanceof  ...的实例

console.log(Person instanceof Object)        //true
console.log(person1 instanceof Object)    //true
console.log(person1 instanceof Person)    //true
console.log(person1 instanceof Worker)    //false
console.log(worker1 instanceof Person)    //true

 

JS面向对象笔记