老生常谈JavaScript面向对象基础与this指向问题


Posted in Javascript onOctober 16, 2017

前 言

我们的程序语言经历了从“面向机器”、到“面向过程”、再到“面向对象”的一个过程。而JavaScript是一门基于对象的一门语言,它介于面向过程与面向对象之间。在学习JavaScript的过程中,OOP是非常重要的一环,下面我们来一起探讨一下JS中的面向对象吧!!!

1 、OOP的基础问题

1.1什么是面向过程和面向对象?

面向过程:专注于如何去解决一个问题的过程步骤。编程特点是由一个个的函数去实现每一步的过程步骤,没有类和对象的概念。

面向对象:专注于由哪一个对象来解决这个问题。编程特点是出现了一个个的类,从类中拿到这个对象,由这个对象去解决具体的问题。

对于调用者来说,面向过程需要调用者自己去实现各种函数。而面向对象,只需要告诉调用者对象中具体方法的功能,而不需要调用者了解方法中的实现细节。

1.2面向对象的三大特征

继承、封装、多态

1.3类和对象的关系

① 类:一类具有相同特征(属性)和行为(方法)的集合。

比如:人类-->属性:身高、体重、性别 方法:吃饭、说话、走路

② 对象:从类中,拿出具有确定属性值和方法的个体。

比如:张三-->属性:身高180、体重180 方法:说话-->我叫张三,身高180

③ 类和对象的关系

类是抽象的,对象是具体的(类是对象的抽象化,对象是类的具体化)

解释一下:

类是一个抽象的概念,只能说类有属性和方法,但是不能给属性赋具体的值。比如说人类有姓名,但是不能说人类的姓名叫啥。。。

对象是一个具体的个例,是将类中的属性进行具体赋值而来的个体。比如说张三是人类的一个个体,可以说张三的姓名叫张三。也就是张三对人类的每一个属性进行了具体的赋值,那么张三就是由人类产生的一个对象。

2、 JavaScript中的面向对象

2.1创建类和对象的步骤

①创建一个类(构造函数):类名必须使用大驼峰法则,即每个单词的首字母必须大写。

function 类名(属性1){
  this.属性1 = 属性1;
  this.方法 = function(){
   //方法中要调用自身属性,必须要使用this.属性
  }
}

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

var obj = new 类名(属性1的具体值);

obj.属性; 调用属性

obj.方法(); 调用方法

③注意事项

>>>通过类名,new出一个对象的过程,叫做“类的实例化”

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

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

>>>类名必须使用大驼峰法则,注意与普通函数的区别。

2.2两个重要属性constructor和instanceof

①constructor:返回当前对象的构造函数

>>>zhangsan.constructor = Person; √

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

>>>lisi instanceof Person √ lisi是通过Person类new出的

>>>lisi instanceof Object √ 所有对象都是Object的实例

>>>Person instanceof Object √ 函数本身也是对象

3、 JavaScript中的this指向问题

在上一部分中,我们创建了一个类,并通过这个类new出了一个对象。 但是,这里面出现了大量的this。 很多同学就要懵逼了,this不是“这个”的意思吗?为什么我在函数里面写的this定义的属性,最后到了函数new出的对象呢??

3.1谁最终调用函数,this就指向谁!

① this指向谁,不应该考虑函数在哪声明,而应该考虑函数在哪调用!!

② this指向的,永远只可能是对象,不可能是函数!!

③ this指向的对象,叫做函数的上下文context,也叫函数的调用者。

3.2this指向的规律(与函数的调用方式息息相关!)

① 通过函数名()调用的,this永远指向window

func(); // this--->window
//【解释】 我们直接用一个函数名()调用,函数里面的this,永远指向window。

② 通过对象.方法调用的,this指向这个对象

// 狭义对象
 var obj = {
  name:"obj",
  func1 :func
 };
 obj.func1(); // this--->obj
//【解释】我们将func函数名,当做了obj这个对象的一个方法,然后使用对象名.方法名, 这时候函数里面的this指向这个obj对象。

 // 广义对象
 document.getElementById("div").onclick = function(){
  this.style.backgroundColor = "red";
}; // this--->div
//【解释】对象打点调用还有一个情况,我们使用getElementById取到一个div控件,也是一种广义的对象,用它打点调用函数,则函数中的this指向这个div对象。

③ 函数作为数组的一个元素,用数组下标调用,this指向这个数组

var arr = [func,1,2,3];
arr[0](); // this--->arr
//【解释】这个,我们把函数名,当做数组中的一个元素。使用数组下标调用,则函数中的this将指向这个数组arr。

④ 函数作为window内置函数的回调函数使用,this指向window。比如setTimeout、setInterval等

setTimeout(func,1000);// this--->window
//setInterval(func,1000);
//【解释】使用setTimeout、setInterval等window内置函数调用函数,则函数中的this指向window。

⑤ 函数作为构造函数,使用new关键字调用,this指向新new出的对象

var obj = new func(); //this--->new出的新obj
//【解释】这个就是第二部分我们使用构造函数new对象的语句,将函数用new关键字调用,则函数中的this指向新new出的对象。

3.3关于this问题的面试题

var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',

prop: {


fullname: 'Aurelio De Rosa',


getFullname: function() {



return this.fullname;


}

}
};
console.log(obj.prop.getFullname()); 
// 函数的最终调用者 obj.prop 
   
var test = obj.prop.getFullname;
console.log(test()); 
// 函数的最终调用者 test() this-> window
   
obj.func = obj.prop.getFullname;
console.log(obj.func()); 
// 函数最终调用者是obj
   
var arr = [obj.prop.getFullname,1,2];
arr.fullname = "JiangHao";
console.log(arr[0]());
// 函数最终调用者数组

好了,这篇博客,我们了解了什么是面向对象、类和对象的关系、JS中声明类与对象的步骤,以及重点讲解的this指向问题! 希望能够帮助大家真正的理解了this的认知,下面我会继续给大家分享关于面向对象方面的问题。多谢大家的支持!!!

以上这篇老生常谈JavaScript面向对象基础与this指向问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之三
Jan 03 Javascript
jquery获取div距离窗口和父级dv的距离示例
Oct 10 Javascript
jquery获取下拉框中的循环值
Feb 08 Javascript
详解windows下vue-cli及webpack 构建网站(三)使用组件
Jun 17 Javascript
浅析JS中常用类型转换及运算符表达式
Jul 23 Javascript
用JS实现简单的登录验证功能
Jul 28 Javascript
Bootstrap table使用方法汇总
Nov 17 Javascript
纯JS实现出生日期[年月日]下拉菜单效果
Jun 01 Javascript
vue实现点击当前标签高亮效果【推荐】
Jun 22 Javascript
用Node提供静态文件服务的方法
Jul 06 Javascript
使用JavaScript解析URL的方法示例
Mar 01 Javascript
antd-mobile ListView长列表的数据更新遇到的坑
Apr 08 Javascript
echarts饼图扇区添加点击事件的实例
Oct 16 #Javascript
Django中使用jquery的ajax进行数据交互的实例代码
Oct 15 #jQuery
JS继承与闭包及JS实现继承的三种方式
Oct 15 #Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
Oct 15 #Javascript
Vue 2.0入门基础知识之内部指令详解
Oct 15 #Javascript
JS中的多态实例详解
Oct 15 #Javascript
vue跨域解决方法
Oct 15 #Javascript
You might like
WINDOWS 2000下使用ISAPI方式安装PHP
2006/09/05 PHP
使用PHP导出Redis数据到另一个Redis中的代码
2014/03/12 PHP
php运行时动态创建函数的方法
2015/03/16 PHP
详解PHP实现执行定时任务
2015/12/21 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
学习ExtJS accordion布局
2009/10/08 Javascript
让网页跳转到指定位置的jquery代码非书签
2013/09/06 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
Nodejs学习笔记之测试驱动
2015/04/16 NodeJs
jQuery往返城市和日期查询实例讲解
2015/10/09 Javascript
分享JavaScript与Java中MD5使用两个例子
2015/12/23 Javascript
js+html5实现canvas绘制椭圆形图案的方法
2016/05/21 Javascript
jQuery实现表格隔行及滑动,点击时变色的方法【测试可用】
2016/08/20 Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
2016/11/06 Javascript
详解Angular路由 ng-route和ui-router的区别
2017/05/22 Javascript
微信小程序实现皮肤功能(夜间模式)
2017/06/18 Javascript
深入浅出webpack教程系列_安装与基本打包用法和命令参数详解
2017/09/10 Javascript
Angular实现下拉框模糊查询功能示例
2018/01/03 Javascript
Angular 向组件传递模板的两种方法
2018/02/23 Javascript
基于Vue 2.0 监听文本框内容变化及ref的使用说明介绍
2018/08/24 Javascript
使用JS判断页面是首次被加载还是刷新
2019/05/26 Javascript
Openlayers实现扩散的动态点(水纹效果)
2020/08/17 Javascript
用python登录Dr.com思路以及代码分享
2014/06/25 Python
Python带动态参数功能的sqlite工具类
2018/05/26 Python
Python headers请求头如何实现快速添加
2020/11/03 Python
体育纪念品、亲笔签名的体育收藏品:Steiner Sports
2020/07/31 全球购物
static全局变量与普通的全局变量有什么区别
2014/05/27 面试题
客服端调用EJB对象的几个基本步骤
2012/01/15 面试题
公司领导班子对照材料
2014/08/18 职场文书
2014幼儿园家长工作总结
2014/11/10 职场文书
2014企业年终工作总结
2014/12/23 职场文书
社区党支部承诺书
2015/04/29 职场文书
新学期主题班会
2015/08/17 职场文书
公司管理建议书
2015/09/14 职场文书
Python Pandas解析读写 CSV 文件
2022/04/11 Python