前  言

          

 学过程序语言的都知道,我们的程序语言进化是从“面向机器”、到“面向过程”、再到“面向对象”一步步的发展而来。类似于汇编语言这样的面向机器的语言,随着时代的发展已经逐渐淘汰;而面向过程的语言也只有C语言老大哥依然坚挺;现在主流的语言(例如Java、C++、PHP等)都是面向对象的语言。 而我们的JavaScript语言,恰恰介于面向过程与面向对象之间,我们称它为“基于对象”的语言。但是,JS中的OOP依然是我们学习JS的重要一环,当然像“继承”“封装”这样的面向对象特征,都是由模拟实现的。今天,我们就一起来探讨一下JS中的面向对象吧!

一、OOP基础知识

1类和对象

面向对象编程(OOP)  思维导图

1、类:

    一类具有相同的特征(属性)和行为(方法)的集合。
      eg:人类--> 属性:身高、性别; 方法:吃饭、说话
2、对象:

    从类中拿出具有确定属性值和方法的个体。
      eg:张三--> 属性:身高:170、 体重;50kg; 方法: 说话-->我叫张三,身高170

3、类和对象的关系
      类是抽象的,对象是具体的。 (类是对象的抽象化,对象是类的具体化)
      类是一个抽象的概念,只能说类属性和方法,但是,不能给属性赋具体的值
        比如:人类有姓名,但是不能说人类的姓名叫什么。。。。
      对象是一个具体的个例,是将类中的属性进行具体赋值而来的个体。
        比如:张三是人类的一个个体,可以说张三的姓名叫张三。也就是,张三对人类的每一个属性进行了具体的赋值,那么张三就是由人类产生的一个对象。

4、使用类和对象的步骤:
  ① 创建一个类(构造函数):类名必须使用大驼峰法则。即,每个单词的首字母都要大写,

  1. function 类名(属性值1,属性值2,...){
  2. this.属性1 = 属性值1
  3. this.属性2 = 属性值2
  4. ...
  5. this.方法 = fucntion(形参){
  6. //方法中要调用自身属性必须使用thi.属性
  7. }
  8. }

  ② 通过类,实例化(new)出一个对象:

  1. var obj = new 类名(属性值);
  2. obj.属性; //调用属性
  3. obj.方法(); //调用方法

  ③ 注意事项:
       1、通过类名,new出一个对象的过程,叫做"类的实例化";

         2、类中的this,会在实例化的时候指向新new出的对象。
          所以,this.属性、 this.方法 实际上是将属性和方法绑定在即将new出的对象上面;

       3、在类中,要调用自身的属性,必须使用this.属性。如果,直接使用变量名,则无法访问对象的属性。

       4、类名必须使用大驼峰法则,注意与普通函数的分。
5、两个重要属性
    ① constructor :返回当前 对象 的构造函数。
     

  1.  zhangsan.constructor == Person;

    ② instanceof :检测一个对象是不是一个类的实例;

  1. lisi instanceof Person lisi是通过Personnew出的
  2. lisi instanceof Object 所有对象都是Object的实例
  3. Person instanceof Object 函数本身也是对象

6、广义对象与狭义对象:
  ① 狭义对象:只有属性和方法,除此之外没有任何其他内容;

  1. var obj = {};
  2. var obj = new Object();

  ② 广义对象: 用字面量声明的基本数据类型不是对象,不能够添加属性和方法
    除了用字面量声明的基本数据类型外JS中万物皆对象。换句话说,只要能够添加属性和方法的变量,都可以称之为对象。

  1. var s = "12"; //不是对象
  2. s.name = "aaa";
  3. console.log(typeof(s)); //string
  4. console.log(s.name); // undefined 字面量声明的字符串不是对象,不能添加属性
  5.  
  6. var s = new String("123"); //是对象
  7. s.name = "aaa";
  8. console.log(typeof(s)); //object
  9. console.log(s.name); // aaa 使用new关键字声明的字符串是对象,能添加属性和方法

2OOP的属性和方法

成员属性和成员方法

1、在构造函数中,使用this.属性声明,或者在实例化出对象以后,使用"对象.属性"追加的,都属于成员属性或成员方法。也叫实例属性和实例方法
  成员属性/成员方法: 是属于由类new出的对象的。
  需要使用"对象名.属性名"调用.

私有属性和私有方法

2、通过"类名.属性名"、"类名.方法名"申明的属性和方法,称为静态属性、静态方法 。也叫类属性和类方法;
    类属性/类方法,是属于类的(属于构造函数)。
    通过"类名.属性名"调用
3、成员属性是属于实例化出的对象的,只能使用对象调用;
    静态属性是属于构造函数的,只能使用类名调用。

私有属性和私有方法

4、在构造函数中使用var申明的变量称为私有属性,使用function申明的函数称为私有方法

  1. function Person (){
  2.   var num = 1 //私有属性
  3.   function func(){} //私有方法
  4. }

私有属性和私有方法的作用域,只在构造函数中有效。即,只能在构造函数内部使用,在构造函数外部,无论使用对象还是类名都无法调用。

 
代码解释
 
  1. function Person(name){
  2. this.name = name;     //声明成员属性
  3. var sex = "男";             //私有属性
  4. this.sayTime = function(){      //声明成员方法
  5. alert("我说当前时间为"+getTime());
  6. }
  7. this.writTime = function(){
  8. alert("我写了当前时间为"+getTime());  //调用私有方法
  9. }
  10. function getTime(){   //私有方法
  11. return new Date;
  12. }
  13. }
      /***************************成员属性/方法*************************/
  14. var zhangsan = new Person("张三");      //类的实例化
  15. zhangsan .age = 18;      //追加成员属性
  16. alert(zhangsan .name);    //调用成员属性
  17.  
  18. /***************************静态属性/方法***************************/
  19.  
  20. Person.count = "60亿"; //声明静态属性
  21.  
  22. alert(Person.count); //调用静态属性
  23. var lisi = new Person("李四");
  24. alert(lisi.count); //undefined 静态属性是属于类的,只能用类名调用
  25.  
  26. /*************************私有属性/方法**************/
  27. lisi.sayTime(); //外部间接调用
  28. lisi.writTime();
2  this指向详解

1、相关知识:

对于判断this的指向问题,总的来说,就是:谁最终调用函数,this就指向谁。

  ① this指向谁,不应该考虑函数在哪声明,而应该考虑函数在哪调用;
  ② this指向的永远只可能是对象,而不可能是函数;
  ③ this指向的对象,叫做函数的上下文(context),也叫函数的调用者。

2、虽然知道了,谁最终调用函数,this就指向谁。但是,还是觉得有点笼统,不够详细。对this的指向问题还是太模糊。

于是,在这里,影子特向大家介绍,this指向问题规律的5条通用判断方法。

  ① 通过 函数名() 调用的,this永远指向window;
  ② 通过 对象.方法 调用的,this指向该对象;
  ③ 函数作为 数组 中的一个元素,用数组下标调用的,this指向该数组;
  ④ 函数作为Window内置函数的 回调函数 使用,this指向window;
    setInterval、 setTimeout
  ⑤ 函数作为构造函数,使用 new关键字 调用,this指向新new出的对象。

下面,将对每条规律,做出案例,以供大家,理解:

  1. <div id="div1"style="width: 200px;height: 200px;background-color: red;">
  2. 这是一个div
  3. </div>
  1. function func(){
  2. console.log(this);
  3. }
  4. var obj ={
  5. func : func
  6. }
  7. function func1(){
  8. func(); //this指向Window
  9. }
  10. //① 通过 函数名() 调用的,this永远指向window;
  11. func(); //this指向Window
  12. //② 通过 对象.方法 调用的,this指向该对象;
  13. obj.func(); //this指向对象obj
  14.  
  15. window.onclick = function(){
  16. document.getElementById("div1").onclick = function(){
  17. func(); // 最终还是使用()调用,所有指向window
  18. }
  19. document.getElementById("div1").onclick = func;//广义对象,指向div1
  20. }
  21.  
  22. //③ 函数最为数组中的一个元素,用数组下标调用的,this指向该数组
  23. var arr = [1,2,3,func,4,5];
  24. arr[3]();
  25.  
  26. //④ 函数作为Window内置函数的回调函数使用,this指向window;
  27. setTimeout(func,1000);
  28.  
  29. //⑤ 函数作为构造函数,使用new关键字调用,this指向新new出的对象。
  30. var obj1 = new func();

下面是一个影子总结的一个综合案例:

  1. /************************综合案例****************/
  2. var obj1 = {
  3. name : "obj1",
  4. arr : [func, 1,{name : "obj2",func : func},3,4],
  5. }
  6. obj1.arr[0](); //最终的调用者是数组,this指向数组
  7. setTimeout(obj1.arr[0],1000); //obj1.arr[0仅仅是取到函数func,但并没有调用。函数的最终调用者是setTimeout,指向window;这个式子相当于setTimeout(func,1000);
  8. setTimeout(obj1.arr[2].func,1000); //函数的最终调用者是setTimeout.原因同上↑
  9. obj1.arr[2].func(); //最终的调用者是{name : obj2,func : func},this指向{name : obj2,func : func}

好了,今天影子给大家分享的东西就这么多了。最后,影子这里还有一道this指向的题,就一这道题结束今天的分享吧。至于答案就留到下次。哈哈。。。

  1. var fullname = 'John Doe';
  2. var obj = {
  3. fullname: 'Colin Ihrig',
  4. prop: {
  5. fullname: 'Aurelio De Rosa',
  6. getFullname: function() {
  7. return this.fullname;
  8. }
  9. }
  10. };
  11.  
  12. console.log(obj.prop.getFullname());
    //??
  13. var test = obj.prop.getFullname;
  14. console.log(test());
  15. //??
  16. obj.func = obj.prop.getFullname;
  17. console.log(obj.func());
          //???
  18. var arr = [obj.prop.getFullname,1,2];
  19. arr.fullname = "JiangHao";
  20. console.log(arr[0]());
  21. console.log(arr[0]);
          //????

面向对象(OOP)--OOP基础与this指向详解的更多相关文章

  1. java基础(3)--详解String

    java基础(3)--详解String 其实与八大基本数据类型一样,String也是我们日常中使用非常频繁的对象,但知其然更要知其所以然,现在就去阅读源码深入了解一下String类对象,并解决一些我由 ...

  2. this指向详解及改变它的指向的方法

    一.this指向详解(彻底理解js中this的指向,不必硬背) 首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是 ...

  3. Qt零基础教程(四) QWidget详解篇

    在博客园里面转载我自己写的关于Qt的基础教程,没次写一篇我会在这里更新一下目录: Qt零基础教程(四) QWidget详解(1):创建一个窗口 Qt零基础教程(四) QWidget详解(2):QWid ...

  4. Qt零基础教程(四)QWidget详解(3):QWidget的几何结构

    Qt零基础教程(四)  QWidget详解(3):QWidget的几何结构 这篇文章里面分析了QWidget中常用的几种几何结构 下图是Qt提供的分析QWidget几何结构的一幅图,在帮助的 Wind ...

  5. mysql基础篇 - SELECT 语句详解

    基础篇 - SELECT 语句详解         SELECT语句详解 一.实验简介 SQL 中最常用的 SELECT 语句,用来在表中选取数据,本节实验中将通过一系列的动手操作详细学习 SELEC ...

  6. [五]基础数据类型之Short详解

      Short 基本数据类型short  的包装类 Short 类型的对象包含一个 short 类型的字段      原文地址:[五]基础数据类型之Short详解   属性简介   值为  215-1 ...

  7. Java基础-面向接口编程-JDBC详解

    Java基础-面向接口编程-JDBC详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JDBC概念和数据库驱动程序 JDBC(Java Data Base Connectiv ...

  8. ELK&ElasticSearch5.1基础概念及配置文件详解【转】

    1. 配置文件 elasticsearch/elasticsearch.yml 主配置文件 elasticsearch/jvm.options jvm参数配置文件 elasticsearch/log4 ...

  9. Linux基础知识之挂载详解(mount,umount及开机自动挂载)

    Linux基础知识之挂载详解(mount,umount及开机自动挂载) 转载自:http://www.linuxidc.com/Linux/2016-08/134666.htm 挂载概念简述: 根文件 ...

随机推荐

  1. DevTool开发者工具

    DevTool开发者工具 chrome的开发者工具可以说是十分强大了,是web开发者的一大利器,作为我个人而言平时用到的几率很大,相信大家也很常见,但是不要仅仅停留在点选元素看看样式的层面上哦,跟着我 ...

  2. Java 多线程(一) 基础知识与概念

    多线程Multi-Thread 基础 线程概念 线程就是程序中单独顺序的流控制. 线程本身不能运行,它只能用于程序中. 说明:线程是程序内的顺序控制流,只能使用分配给程序的资源和环境. 进程 进程:执 ...

  3. 201521123082 《Java程序设计》第14周学习总结

    201521123082 <Java程序设计>第14周学习总结 标签(空格分隔):java 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. Answ ...

  4. 201521123089 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码1.1 com.parent包中Child.java文件能否编译通过?哪 ...

  5. 201521123090《JAVA程序设计》第二周学习总结

    1. 本章学习总结 java基本数据类型 String类对象使用 枚举类型及switch分支 容器的概念 2. 书面作业 Q1.使用Eclipse关联jdk源代码(截图),并查看String对象的源代 ...

  6. backtrack 使用Tab键补全命令

    刚安装个BackTrack5(基于Ubuntu)做安全测试,发现默认安全设置级别很高,连ssh服务默认都关闭,root下不能使用tab键补全命令,这个就真不方便了.原因是root的配置文件注释了三行脚 ...

  7. 201521123067 《Java程序设计》第13周学习总结

    201521123067 <Java程序设计>第13周学习总结 1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 Q1. 网络基 ...

  8. 201521123032 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...

  9. cms内容模型标签

    内容模块 内容模块PC标签调用说明 模块名:content 模块提供的可用操作 操作名 说明 lists 内容数据列表 relation 内容相关文章 hits 内容数据点击排行榜 category ...

  10. linux fork两次避免僵尸进程的程序(简单)

    #include<stdio.h> #include<unistd.h> int main() { pid_t pid,pid1; int status; ) { printf ...