您现在的位置:首页 >> 前端 >> 内容

JS面向对象

时间:2017/4/26 9:14:29 点击:

  核心提示:JS面向对象:这种模式的缺点是无法识别实例是属于哪一个对象。function createPerson(name,age,place){ var obj = {}; obj.name=name; ob...

JS面向对象:这种模式的缺点是无法识别实例是属于哪一个对象。

function createPerson(name,age,place){
       var obj = {};
       obj.name=name;
       obj.age=age;
       obj.place=place;
       obj.getName= function(){
       console.log('该对象的名字是'+this.name)
        };
       return obj;
}
//工厂模式对象创建方式,与寄生构造函数模式作比较
var person1 = createPerson('lucy','23','swu');

构造函数模式

这种模式的优点是可以识别构造函数模式,他的优点是可以识别实例是属于哪一个对象,缺点是无法实现某些函数的共用,即每个方法都要在都要在实例上创建一遍

function Person(name,age,place) {
        this.name = name;
        this.age = age;
        this.place = place;
        this.getName = function () {
        console.log('Name: '+this.name);
        }
    }
var person = new Person('lucy',23,'西南大学');
//Name:lucy
person.getName();
//true
console.log(person instanceof Person); 

原型模式

每个函数都有一个prototype属性,这个属性指向这个函数的原型对象,同时每个原型都有一个constructor属性,指向该函数,每个函数的实例都有一个默认的proto属性指向该原型对象,原型的意思有点类似与Java中的静态变量,在内存中分配出一块空间,多个实例共享这个空间。

    function person() {
    }
    person.prototype.name='lucy';
    person.prototype.age=23;
    person.prototype.place="西南大学";

    var p1 = new person();
    var p2 = new person();
    //lucy
    console.log(p1.name);
    p1.name='kathy';
    //kathy
    console.log(p1.name);
    //lucy
    console.log(p2.name);
    //false
    alert(p1.name===p2.name); 

原型链查找对象

先在该实例中查找有没有这个属性,如果有,就执行,不会再向上一级查找,如果没有找到,就去该实例的原型对象中去寻找。 isPrototypeOf()用来判断某个属性是否是该实例有一个指向原型对象的指针。

hasOwnProperty()用来判断某个属性是否是某个实例的实例属性。

function person() {

}
person.prototype.name='lucy';
person.prototype.age=23;
person.prototype.place="西南大学";
var p1 = new person();
p1.name='kathy';
//true
alert(person.prototype.isPrototypeOf(p1));
//true
alert(p1.hasOwnProperty('name'));
function judge(sx,object) {
    if ( sx in object && !object.hasOwnProperty(sx)){
        alert(true);
    }
    else {
        alert(false);
    }
}
//false
judge('name',p1);

原型模式的缺点是无法个性,就是如果一组属性你不想共有,单独使用原型模式是无法实现的。

一种更简单的原型模式,这种模式的特点是会重写整个原型对象,constructor会指向Object而不是该对象。

Person.prototype={
   constructor:Person, //1
   name:'Lucy',
   age:23,
   place:'swu',
   getName:function () {
       alert(this.name);
   }
};
var person = new Person();
//true
//将1注释之后输出为false;
alert(person.constructor===Person);

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

这种方式可以将构造函数模式和原型模式的优点结合起来,既能实现函数的复用,又可以自定义属性。

    function Person(name,age,job) {
        this.name=name;
        this.age=age;
        this.job=job;
        this.films = ['1','2','3'];
    }
    Person.prototype={
        constructor:Person,
        getName:function () {
            alert(this.name);
        }
    };

动态原型模式

这种模式能很好的封装信息,又可以避免多次重写原,注意这里不可以使用字面量的方式创建原型,因为这会切断,实例与新原型之间的联系。

function Person(name,age,job) {
        this.name=name;
        this.age=age;
        this.job=job;
        this.films = ['1','2','3'];
        if (typeof this.getName != 'function'){
                Person.prototype.getName = function(){
                    alert(this.name);
                }
        }
}

寄生构造函数模式

这种模式基本上与工厂模式一样, 只是在创建对象的时候有一点区别

        function Person(name,age,place){
               var obj = {};
               obj.name=name;
               obj.age=age;
               obj.place=place;
               obj.getName= function(){
               console.log('该对象的名字是'+this.name)
                };
               return obj;
        }
        //工厂模式对象创建方式,与寄生构造函数模式作比较
        var person1 =new Person('lucy','23','swu'); 
        person1.getName();    

稳妥构造函数模式

    function Person(name,age,job){
        var o = new Object();
        o.sayname = function(){
        alert(name);
        };
        return o;
    }

继承

原型链继承

使子对象的原型对象指向父对象的一个实例 子对象的原型对象拥有父对象的所有实例属性,但是也可以访问到父对象的原型方法,以及原型属性,因为此时,子对象的原型对象也指向了父对象的原型对象

原型链继承的搜索方式,先在实例中寻找,然后到子对象的原型对象中寻找,然后到父对象的原型对象中去寻找。

function Parent() {
    this.name = 'yige';
    this.age = 17;
    this.place = 'swu';

}
Parent.prototype.getName=function () {
    alert(this.name);
};
function Sub() {

}
Sub.prototype = new Parent();
//yige
alert(Sub.prototype.name);

借用构造函数

也就是冒充函数的方法,使用 apply 或者 call 方法

    function Parent(name){
        this.name = name;
    }
    function Sub(){
    Parent.call(this,'lucy')
    }
    var sub1 = new Sun();
    //'lucy'
    alert(sub1.name);

组合继承

不需要共用的属性使用构造函数继承,需要共用的属性和方法使用原型链继承,这也是最常用的一种继承方式。

原型式继承

基本思想是父对象直接赋值给新对象的原型,新的实例属性各自定义,引用类型公有。

function object(o){
    function F(){}
    F.prototype = o;
    return new F();
}
var person ={
    name: 'kathy',
    friends: ['1','2','3']
}
var person1 = object(Person);

寄生式继承

基本思路是类似于工厂模式,创建一个函数,这个函数返回一个对象,然后调用这个函数中的方法。

寄生组合式继承

function inPtototype(subType,superType){
    var prototype =object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}

Tags:JS S面 面向 向对 
作者:网络 来源:zhisais的博客