初识面向对象

2017-12-26  本文已影响0人  Simon海明月

日期:2017-12-26 by:simoon

javaScript中一切都是对象,对象的来源于null。

什么是类?

    类:具有一些特点,就是属性(property)。同时具有一些行为,就是方法e(method);

    类是某一类具有相同的特性。而其中的某一个就是对象的实例。

那么如何理解面向过程和面向对象呢。
举一个现实中的例子:
比如说:我叫小明去帮我买个汉堡包这个例子。

面向过程如下:
//面向过程:
            console.log("我喊小明过来");
            console.log("小明过来了");
            console.log("给你十块钱去KFC给我买汉堡,记得找零钱");
            console.log("小明拿着钱下去去肯德基");
            console.log("排队,跟营业员沟通");
            console.log("给钱,等待");
            console.log("营业员找钱,准备食物");
            console.log("小明收好零钱,拿好汉堡,准备回来");
            console.log("把汉堡给我,给我零钱);*/
面向对象如下:
//面向对象
            var tech={
                name:"李响",
                act1:function(){
                    console.log("我喊小明过来");
                },
                act2:function(){
                    console.log("给小明十块钱去KFC给我买汉堡,记得找零钱");
                },
                act3:function(){
                    console.log("拿汉堡,收好零钱");
                }
            };
            var xiaoming={
                name:"小明",
                age:18,
                act1:function(){
                    console.log("被老师喊过来");
                },
                act2:function(){
                    console.log("拿钱去KFC");
                },
                act3:function(){
                    console.log("排队");
                }
            var saler={
                name:"小花",
                age:20,
                act1:function(){
                    console.log("跟小明眉来眼去,沟通");
                },
                act2:function(){
                    console.log("收钱准备食物");
                },
                act3:function(){
                    console.log("找零,给食物");
                },
            }

javaScript中是自带了很多内置对象的,比如:

var arr = new Array();
var date = newDate();

什么是对象的属性呢?就是它的特点,比如arr就具有长度的属性.

arr.lenght

什么是对象的方法呢?比如:

arr.sort();
arr.join();
arr.reverse();

这样就很好理解javascript中的对象的属性和方法了,属性就是具有的特征,而对象就是一种行为。

那么如何自己创建一个对象呢?

字面量创建:
1: var 对象名 = {属性1:方法1,属性2:方法2}
2: var 对象名 = {}
2-1: 对象名.属性1 = 方法1;
2-1: 对象名.属性2 = 方法2;
比如说:

        var obj={};
        obj.name="小花";
        obj.act=function(){
            alert(1);
        }
        obj.cc=function(){
            name:"小红";
            aa:function(){
                alert(this.name);
            }
        }           

这样的obj对象就具有一个name属性,一个sct的方法了,一个cc方法。
那么问题出来了,这里的this指向谁??
回顾:在单独的函数中,匿名函数,this指向window,非匿名函数指向事件源。

如果出现函数的嵌套,这时候this指向离哪个近,就指向哪个。

那么如何改变this的指向呢?方法有两个:

call(a,b,c) 方法可以传多个参数,第一个方法是this的指向,后面的是传入的参数。
apply(a,[b,c])方法传入一个参数和一个数组,如果不是数组,将会报错。
如果什么都不传,相当于函数调用

比如说:

function fn(a,b){
    console.log(this);
    console.log(a+"+"+b+"="+(a+b));
}
fn.call(5,7,8)
控制台输出:5和7+8=15;
function fn(a,b,c){
    console.log(this);
    console.log(a,b,c);
}
fn.apply(6,[5,6,7]);
控制台输出:6和5 6 7

利用上面的特点,我们可以求数组最大值。实现代码如下:

console.log(Math.max.apply(Math,[1,3,55,4]));
···
原理是,apply()没有改变指向,依然指向Math,

关于与保留this的问题

<body>
    <button id="btn">按钮</button>
</body>
<script>
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        function fn1(){
            console.log(this.innerHTML);
        }
    }
    fn1();
</script>

一段这样的代码,控制台输出:Window undefined。为什么呢?
因为这时候this指向的是window。如果想指向btn,那么就需要预保留this。
代码如下:

<body>
    <button id="btn">按钮</button>
</body>
<script>
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        var _this = this;//通过_this预保留
        function fn1(){
            console.log(_this,_this.innerHTML);
        }
        fn1();
    }
</script>

我们可以通过new来创建对象

<body>
    <script>
        var obj = new Object();
        obj.name = "小明";
        obj.act = function(){
            alert(this.name);
        }
        obj.act();
    </script>
</body>

但是这样的创建太麻烦了,所以我们需要工厂函数创建对象。
具体如下:这样就可以重用了。

<body>
    <script>
        function createPerson(n,a){
            var obj = new Object();
            obj.name = n;
            obj.age = a;
            obj.showName = function(){
                alert(this.name);
            }
            // 出厂
            return obj;
        }
        var p1 = createPerson("小花",18);
        var p2 = createPerson("小明",16);
        p1.showName();
        p2.showName();
        console.log(p1.age);
        console.log(p2.age);
    </script>
</body>

当new一个对象时会发生什么呢?

会创建一个实例对象,这是的this指向实例对象。函数会有一个默认的返回值,就是这个对象。

<body>
    <script>
        function CreatePerson(n,a){
            this.name=n;
            this.age=a;
            this.showName=function(){
                alert(this.name);
            }
        }
        var p1 = new CreatePerson("小花",19);
        p1.showName();
        var p2 = new CreatePerson("小明",16);
        p2.showName();
    </script>
</body>

构造函数在解决了上面所有问题,同时为实例带来了类型,但可以注意到每个实例printName方法实际上作用一样,但是每个实例要重复一遍,大量对象存在的时候是浪费内存。

那么如何解决呢?
function Person(nick, age){
    this.nick = nick;
    this.age = age;
    this.sayName = function(){
            console.log(this.nick);
    }
}
var p1 = new Person();

这段代码中的sayname就是每次new 对象都会重复的方法。

构造函数.png

通过这个原理,我们可以抽象重复。

function Person(nick, age){
    this.nick = nick;
    this.age = age;
}
Person.prototype.sayName = function(){
    console.log(this.nick);
}

var p1 = new Person();
p1.sayName();

这时候,相对应的关系如下:


解决方法重复.png

再写个小例子

<script>
        function CreatPerson(n,a){
            this.name = n;
            this.age = a;
            this.showName=function(){
                alert(this.name);
            }
        }
        var p1=new CreatePerson("小明",16);
        p1.showName();
        p1.showAge=function(){
            alert(this.age);
        }
        var p2=new CreatePerson("小花",19);
        p2.showName();
</script>

这里的showName方法就重复了,如何使用原型链来解决呢?

代码如下:

<body>
        function CreatPerson(n,a){
            this.name = n;
            this.age = a;
        }
        CreatPerson.prototype.showName = function(){
            alert(this.name);
        }
        var p1 = new CreatPerson("小花",18);
        p1.showName();
        var p1 = new CreatPerson("小花花",16);
        p1.showName();
        alert(p1.age);
    </script>
    
</body>

最后尝试封装一个数组求和的函数,实现代码如下:

<body>
    <script>
        Array.prototype.sum = function(){
            var result = 0;
            for(var i=0;i<this.length;i++){
                result += this[i];
            }
            return result;
        }
        var arr = new Array(1,2,3,44);
        console.log(arr.sum());
    </script>
</body>

THE END

上一篇下一篇

猜你喜欢

热点阅读