初识面向对象

日期: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() 方法
  • apply()方法

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方法实际上作用一样,但是每个实例要重复一遍,大量对象存在的时候是浪费内存。

那么如何解决呢?
  • 任何函数使用new都是表达式就是构造函数(工厂函数)
  • 每一个函数都会添加一个原型
  • 每个对象都有一个内部属性 proto(规范中没有指定这个名称,但是浏览器都这么实现的) 指向其类型的prototype属性,类的实例也是对象,其proto属性指向“类”的prototype。
    比如有一个代码
function Person(nick, age){
    this.nick = nick;
    this.age = age;
    this.sayName = function(){
            console.log(this.nick);
    }
}
var p1 = new Person();

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

构造函数.png

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

  • 所有函数都会通过原型链来引用类型的prototype
  • prototype相当于特定类型所有实例都可以访问到的一个公共容器
  • 我们可以把重复的东西放到prototype中。
    这时候,把重复的方法挂在到prototype中,代码如下:
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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 普通创建对象和字面量创建对象不足之处:虽然 Object 构造函数或对象字面量都可以用来创建单个对象,但这些方式有...
    believedream阅读 2,340评论 2 18
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,697评论 2 17
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,391评论 3 12
  • 听朋友推荐的,过来看看,这里有些什么。还没看,就先写了。没错我缺钱。18岁的年级,有着108岁心态的我,过早地经历...
    篌寸光阅读 134评论 0 0
  • 有关爷爷的记忆只停留在我七八岁的几个零星的画面,因为爷爷在我读小学的时候就去逝了... 我现在能回忆起也是最难忘的...
    菲子阅读 440评论 3 5