13-JS高级(二)JS高级

面向对象

  • 面向过程的思维方式:就是把解决问题的关注点放到解决问题的每一个详细步骤上;
  • 面向对象的思维方式:就是把解决问题的关注点放到解决问题需要的一系列对象身上。
  • 面向对象是一种思维方式,和我们代码关系不大,它把解决问题的关注点放到了解决问题需要的一系列对象身上。
  • 面向对象是对面向过程的封装。

什么是对象:

  • 万物皆对象;
  • JavaScript 中的所有事物都是对象:字符串、数字、数组、日期,等等;
  • 在 JavaScript 中,对象是拥有属性和方法的数据。
  • 在js中,键值对的组合就是对象,键值对有属性和方法。

属性和方法

  • 属性是与对象相关的值,用来描述对象的相关信息,也叫对象的特征;
  • 方法是能够在对象上执行的动作,对象的行为。

面向对象和面向过程的简单比较

  • 使用面向过程思维向body中添加div:
<script>
    var div = document.createElement("div");
    div.style.width = "100px";
    div.style.height = "100px";
    div.style.backgroundColor = "red";
    document.body.appendChild(div);
</script>
  • 使用面向对象思维解决:
<script src="../jquery-1.11.1.min.js"></script>
<script>
    $("body").append("<div style='height:100px;width:100px;border:1px solid red;background-color: green'></div>");
</script>

函数封装

  • 优点:使代码复用性更高;
  • 缺点:
  • 全局变量污染, 解决方式:使用面向对象。
  • 代码结构不清晰,维护不方便: 在对象里面再将功能相近的函数放到一个对象里。
var person = {
    learn:function (course){
        console.log("我正在主修" +couse);
    }
    eat:function(meal){
        console.log("我正在吃"+meal);
    }
}
person.eat("午饭");
  • 使用对象进行封装后的优势:
  • 暴露在全局的只有一个对象名,不会造成全局变量污染;
  • 使用对象将代码进行功能模块的划分,有利于日后的维护。

JS高级讲义

面向对象的三大特性

  • 三大特性:封装、继承、多态。
  • 封装
    把一些属性和方法装到一个对象里面,让它们变得有意义。
  • 继承
    把别的对象的方法和属性拿过来用,就是继承
  • 混入式继承(最常用):for in
    <!--混入式继承:for in-->
    <script>
        var obj = {
            name:"刘德华",
            say:function () {
                console.log("世界,你好,我是刘德华!!!");
            }
        };

        var person = {};

        for (var k in obj) {
            //k可以获取到对象的每一个属性
            //obj[k]可以获取到对象的每一个属性的值
            //这里使用k给对象新增属性时候,不可以使用点语法;同时,这里获取属性的值时也不可以使用点语法
            person[k] = obj[k];
        }

        person.say();
    </script>
- 注:这里使用k给对象新增属性时候,不可以使用点语法;同时,这里获取属性的值时也不可以使用点语法。
  • 多态
    多态是在强类型语言中比较常用,JavaScript中没有相应的体现。
    使用父类的对象接受子类的对象(JavaScript中用不到);
    多态:父类的属性和方法可以供所有子类共享,但是父类不能访问子类的属性和方法,使用多态来隐藏不同

创建对象的四种方式

  • 使用字面量创建对象
   var o = {key:value, key:value...}
  • 只能创建一次性对象,用一个创建一个,不能复用,如果要创建多个对象,会造成代码冗余,资源浪费;
  • 使用内置构造函数创建对象
   var o = new Object();
   var o = new Array();
  • 创建出来的对象都是空的对象,利用对象的动态特性手动的去为对象添加属性和方法。造成代码重复。
  • 封装简单的工厂函数(不推荐使用)
function createObj(singer,song){
     var obj = new Object();
     obj.name = singer;
     obj.song = song;
     obj.sing = function (){
       console.log("让我来为你唱首歌);
     }
     return obj;
}
var obj1 = createObj("那英","默");
var obj2 = createObj("南金岭","逆流成河");
  • 自定义构造函数
    • 构造函数是用来初始化对象的(给对象新增成员),构造函数首字母要大写,以示区分;
    • new是用来创建对象的。
function Person(){
        //默认隐含操作,把new出来的Object赋值给this
        this.name = xxx;
        this.age = 20;
        this.study = function(){
            //code
        }
        //默认隐含操作:返回this
}
var p = new Person();
//如果调用的时候没有参数,小括号可以省略,可以使用var p = new Peron;
    0.构造函数名首字母要大写;
    1.构造函数一般和new关键字一起使用;
    2.构造函数返回值默认为新创建好的对象, 如果手动返回基本数据类型,不影响默认返回值,如果返回的是对象,那么新创建出来的对象将不会返回,取而代之的是return后面的对象。一般都不会去写这个return语句。
  • 构造函数与普通函数的区别:

    • 构造函数也属于函数的一种;
    • 构造函数是用来初始化对象的,一般和new关键字一块使用;
    • 构造函数里面的this指向使用new创建出来的对象;
    • 构造函数的返回值:默认返回我们创建
      出来的对象。
  • 构造函数(constructor)的执行步骤:
    1.使用new关键字创建对象;
    2.调用构造函数,隐含操作:将new创建出来的对象赋值给构造函数内的this;
    3.使用this给新创建出来的对象增加成员;
    4.默认返回新创建出来的这个对象(普通的函数,如果不写返回语句,会返回undefined)。

  • 对象是无序的键值对的集合。

  • js中提供了两个方法来调用其他对象的方法:

  • call;

  • apply。

<!--获取对象的具体类型-->
var typeStr = Object.prototype.toString.call(想要获取类型的对象);
//[object Array]
typeStr = typeStr.slice(8,-1);
  • 注:
function Animal(name,age,barkWay){
    this.name = name;
    this.age = age;
    this.bark = barkWay;
}
Animal("","",function (){
    console.log("我是张学友!!!");
});
window.bark();  //我是张学友!!!
  • 如果像使用正常函数一样使用构造函数,构造函数中的this将不再指向新创建出来的对象(因为根本就没有创建对象);
  • 此时构造函数中的this指向的是window全局对象;
  • 这时使用this给对象添加成员的时候,全部都添加到window上。

原型

构造函数存在问题

构造函数中的方法,每新创建一个对象的时候,该对象都会重新的创建一次这个方法,每个独享独占一个方法
但是该方法内容完全相同,所以造成资源浪费

1.解决办法1
将构造函数内的方法,进行提取,放在构造函数外面,并将该函数赋值给构造函数内的方法;
那么创建出来的对象,都会指向构造函数外面的这个函数,达到共享的目的;
此时使用这种方式写好的方法中的this指向的就是调用该方法的对象(谁调用指向谁)(默认的指向window);

问题:1.全局变量增多,造成全局变量污染;2.代码结构混乱,不容易维护

2.解决办法2
使用原型

原型是什么?

在构造函数创建出来的时候,系统会默认的创建并关联一个对象,这个对象就是原型,原型对象默认是空对象。
默认的原型对象中会有一个属性constructor指向该构造函数。
  • 如何访问构造函数的原型:构造函数.prototype。
  • prototype是构造函数的属性,和对象没有关系。

原型的作用

原型对象中的成员(属性和方法),可以被使用和它关联的构造函数创建出来的所有对象使用。
所以我们可以将构造函数中需要创建的函数,放到原型对象中存储,这样就解决全局变量污染及代码结构混乱的问题。

1. 实例化:通过构造函数创建对象的过程。
2. 实例:通过构造函数实例化出来的对象就是该构造函数的一个实例。
3. 说实例的时候,一定要指定对应的构造函数:xxx对象是xxx构造函数的实例。

原型对象的使用

1. 构造函数.prototype;
2. 使用对象的动态特性,为原型对象添加成员(添加成员较少时候推荐使用);
3. 直接替换原型对象(添加成员比较多的时候推荐使用)。

注意事项:
    直接替换原型对象,会导致替换之前创建的对象的原型和替换之后创建的对象的原型不是同一个。

原型的使用该注意事项

1.使用对象访问属性和方法的时候,会先在对象中查找,如果找到了就直接使用;如果没有找到,就去原型中查找。如果原型中还没有,如果是属性,就是undefined,如果是方法,就会报错。

2.使用对象设置属性的时候,只会在对象本身中查找,不会去原型中查找,如果在对象本身中没有找到这个属性,则给该对象新增一个属性,如果在对象中有这个属性,修改这个属性;

3.如果在原型对象中有引用类型的属性,那么使用对象进行修改该属性内容,则其他所有跟这个原型对象相关的对象都会受到影响;

4.一般情况下不会将属性添加到原型对象中,只会将需要共享的方法,添加到原型对象中。
三角关系
__proto__
  • 通过构造函数访问原型对象:Person.prototype;
  • 通过对象访问原型对象:p.__proto__;
    1.这个属性不是标准属性,所以存在通用性问题;
    2.为了保证通用性,一般不推荐使用这个属性;
    3.调试的时候,可以使用这个属性;
    4.这个属性是原型中的属性。
constructor
  • 原型对象在创建出来的时候,会默认的有一个constructor属性,指向对象的构造函数;

  • 通过对象访问构造函数:p.constructor('','');,相当于直接使用Person('','');

  • 替换原型时候的注意事项:
    在新替换的原型中,constructor属性会变成Object,会影响三角结构关系的合理性;
    so,在新替换的原型中,为了保证整个构造函数---原型---对象之间的合理性,应手动添加constructor属性,赋值为关联的构造函数(constructor: Person)。

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

推荐阅读更多精彩内容

  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,424评论 3 12
  • 继承 一、混入式继承 二、原型继承 利用原型中的成员可以被和其相关的对象共享这一特性,可以实现继承,这种实现继承的...
    magic_pill阅读 1,062评论 0 3
  • 第5章 引用类型 引用类型的值(对象)是引用类型的一个示例。在ECMAScript 中,引用类型是一种数据结构,用...
    力气强阅读 716评论 0 0
  • 1,javascript 基础知识 Array对象 Array对象属性 Arrray对象方法 Date对象 Dat...
    Yuann阅读 911评论 0 1
  • /于心不语✨ 01 “偶尔羡慕情侣,偶尔庆幸自由。” 这是我认识雨嘉以来听她说过的关于爱情最多的话了,当听她讲起那...
    于心不语阅读 1,030评论 11 4