面向对象

1.什么是对象?

对象是一个整体(相当于是一个盒子,对外是封闭的),对外提供了一些操作

2.什么是面向对象?

使用对象时,只关注对象提供的功能,并不关注内部的细节。比如JQuery

3.面向对象是一种通用的思想,并非只有编程中能用,任何事情都可以用。

4.JS中的面向对象

(1)面向对象编程(OOP)的特点

  抽象:抓住核心问题(比如,把一个人填写表单提交到数据库,有用户名,密码,身高等等,这样,一个人就变成数据库里面的一条数据记录)

  封装:不考虑内部的实现,只考虑功能的使用(从外面看不到里面,留了几个功能在外面)

  继承:从已有的对象上,继承出新的对象(不改变原有的对象)就是继承属性和方法,先执行父类的构造函数,再添加子类的属性

   特性: -多重继承(有多个父类)

       -多态(父类和子类具有相同的操作,但是不是那么一样)

(2)对象的组成

  方法——函数:过程,动态的(方法和函数也是同一级别,如果是属于某个对象的函数,那就是方法。)

  属性——变量:状态,静态的(变量和属性是同一级别的,如果是自由的,不属于任何对象的,就是变量。但如果是属于某个对象的就是属性了。)

栗子:

var arr=[1,2,3,4,5]; //arr是对象

var a=6; //变量
arr.a=6; //属性

function show(){ //函数
  alert('a');  
}
show();

arr.fn=function(){//方法
  alert('a');
}
fn();

(3)为对象添加方法和属性

  this详解,事件中处理this的本质

    -window(全局函数,变量本身就属于window上的方法和属性)

    -this——函数属于谁(谁发生事件,this就指向谁)

oDiv.onclick=function(){
  alert(this);  //this指向oDiv
}

过去给一个物体添加事件,本质上就是给其添加方法。

this表示当前的方法,属于谁。如上面的栗子,onclick这个方法属于oDiv,所以this就是oDiv。

window

function show(){
  alert(this);
}

show();//显示的是window,也就是说这个this指向的是window

就相当于:
window.show=function(){
   alert(this);
}
show();
自然,这个this就是指向window的

同样的关于变量和属性

var a=12;
alert(a);  //a是变量

alert(window.a);//a是window的属性

不能在系统对象中随意附加方法、属性,否则会覆盖已有方法,属性。

(4)工厂方式

用工厂方式构造对象

工厂:

1.原料

2.加工

3.出厂

规范:构造函数首字母要大写

 function CreatePerson(name,sex)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>工厂方式</title>
    <script>
        function CreatePerson(name,sex){//构造函数,作用是构造一个对象
            //1.原料,创建空白对象,object几乎是空白对象,可以在其身上添加属性和方法
            var obj=new Object();

            //2.加工,添加属性和方法
            obj.name=name;
            obj.sex=sex;

            obj.showName=function(){
                console.info("我的名字叫:"+this.name);
            }
            obj.showSex=function(){
                console.info("我是"+this.sex+"");
            }

            //3.出厂,现在的Obj中已经包含了属性和方法
            return obj;

        }

        var p1=CreatePerson('blue','');
        var p2=CreatePerson('leo','');

        p1.showName();
        p1.showSex();
        p2.showName();
        p2.showSex();

    </script>
</head>
<body>
    
</body>
</html>

但是,工厂方式也存在着一些问题:

1.没有new,一般构造对象是有new的,比如var arr=new Array();

2.每个对象都有一套自己的函数--浪费资源

解释:

var p1=CreatePerson('blue','男');
var p2=CreatePerson('leo','女');

console.info(p1.showName==p2.showName);//false

发现这两个函数对象并不相同,其实这是匿名函数在作怪,因为匿名函数没写一次function,就会诞生一个函数对象。

var a=function(){
  alert('abc');
}

var b=function(){
  alert('abc');
}

alert(a==b);//false

/*其实是匿名函数
上面的和下面的是一致的*/

var a=new Function("alert('abc')");
var b=new Function("alert('abc')");

/*每写一次function就会诞生一个函数对象*/

 (5)解决工厂方式的问题的方法

前面说到this表示当前方法属于谁,但是在有一种情况下会失效,就是函数前面有new 的时候

    function show(){

            console.info(this);
        }

        show();//这个this就是window

        new show();//新创建的对象,这个this就是Object,因为函数前面加了个new,系统会自动创建var this=new Object();

1.针对没有new的问题的解决方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>工厂方式</title>
    <script>
        function createPerson(name,sex){//构造函数,作用是构造一个对象
            //假想的系统内部工作流程var this=new Object();

            //2.加工,添加属性和方法
            this.name=name;
            this.sex=sex;

            this.showName=function(){
                console.info("我的名字叫:"+this.name);
            }
            this.showSex=function(){
                console.info("我是"+this.sex+"");
            }

            /*假想的系统内部工作流程
            return obj;*/

        }
        var p1=new createPerson('blue','');
        var p2=new createPerson('leo','');
        p1.showName();
        p1.showSex();
        p2.showName();
        p2.showSex();
    </script>
</head>
<body>
    
</body>
</html>

2.针对每个对象都有一套自己的函数--浪费资源的问题的解决方法

 prototype(原型)

在CSS中

class  改变一类元素的样式<----->类似于 prototype(原型),给一类元素添加属性和方法

行间样式  改变一个元素的样式,优先级更高<----->类似于给一个对象加方法

在JS中

类,就相当于一个,模子,作用就是用来生产蛋糕的。

对象(实例),就相当于一个,蛋糕,作用就是用来吃的。

 对于 var arr=new Array();

Array(类),不具备实际功能,只能用来构造对象。

arr(对象),真正有功能的东西,被类给构造出来。

 栗子:

 不可能在arr1.sum=function(){},arr2.sum=function(){}

  Array.prototype.sum=function(){},这里就是给类的原型添加方法,这一类里面所有的东西都有这个方法了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>工厂方式1</title>
    <script>
        var arr1=new Array(1,2,3,4,5);
        var arr2=new Array(6,7,8,9,10);

        Array.prototype.sum=function(){
            var result=0;
            var i=0;
            for(i=0;i<this.length;i++){
                result+=this[i];
            }
            return result;
        }
        console.info(arr1.sum());
        console.info(arr2.sum());
    
    </script>
</head>
<body>
    
</body>
</html>

 原型的一个重要应用:可以扩展系统对象,给它添加一些本不支持的方法。

 

        var arr1=new Array(1,2,3,4,5);
        var arr2=new Array(6,7,8,9,10);

        Array.prototype.sum=function(){
            var result=0;
            var i=0;
            for(i=0;i<this.length;i++){
                result+=this[i];
            }
            return result;
        }
        console.info(arr1.sum==arr2.sum);//true

发现arr1.sum和arr2.sum竟然相等了,那是因为它们都等于Array.prototype.sum

 原型既然可以给系统对象添加方法,也可以可自己创造的函数添加方法(构造函数就是类,类就是构造函数,是一个东西

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>工厂方式</title>
    <script>
        function CreatePerson(name,sex){//构造函数,作用是构造一个对象
            this.name=name;
            this.sex=sex;

        }
        CreatePerson.prototype.showName=function(){
                console.info("我的名字叫:"+this.name);
            }
        CreatePerson.prototype.showSex=function(){
                console.info("我是"+this.sex+"");
            }

        var p1=new CreatePerson('blue','');
        var p2=new CreatePerson('leo','');

        p1.showName();
        p1.showSex();
        p2.showName();
        p2.showSex();
    console.info(p1.showName==p2.showName);//true
    </script>
</head>
<body>
    
</body>
</html>

这说明每个对象都同样的函数--节省了资源

 总结:

属性:每个对象都各不相同,就放在构造函数里面

方法:所有对象都一样,就用原型

 还有一个问题:利用了原型,那里面的this指向的是谁呢?

栗子:

Array.prototype.sum=function(){
  this;  
}

var arr=new Array();
arr.sum();
/*可以明白了,this就是指向new出来的对象arr*/

 总结:

  this 永远指向函数运行时所在的对象,而不是函数被创建时所在的对象。匿名函数或不处于任何对象中的函数指向 window 

       1.如果是call,apply,with,指定的this是谁,就是谁 

     2.普通的函数调用,函数被谁调用,this就是谁

(5)原型的优先级

给对象加方法比原型优先级高

栗子:

    
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>工厂方式2</title>
    <script>
        Array.prototype.a=12;
        var arr=[1,2,3];
        console.info(arr.a);

        arr.a=5;
        console.info(arr.a);
        
        delete arr.a;
        console.info(arr.a);
        
    </script>
</head>
<body>
    
</body>
</html>

原文地址:https://www.cnblogs.com/GumpYan/p/5713542.html