javascript 特殊的面向对象以及继承详解(入门篇)
学习Javascript人,大多听说一句话叫js里面一切都是对象。我刚开始接触javascript面向对象编程时候,挺乱的,我当时习惯性的把PHP的面像对象思想套用在js上面,其实js的面向对象与传统的面向对象还是有很多区别的。这里就不再去讲解基础的面向对象是什么了,看这篇文章就默认大家都知道面向对象的概念。
首先,在目前的js版本中,依然没有引入class这个关键词,js里面没有类的概念,其他语言在实例化一个对象的时候,都是使用new 类名来得到实例,而js由于没有class,因此它的面向对象也可以理解为是一种模拟的方式。首先我们来说一下js里面的函数,js里面都函数有一个特点,就是所有的函数都有返回值,如果我们没有手动编写 return。那么函数会返回一个underfind,如果写了,则返回你写的值。这种返回值是在正常的函数调用情况下出现的。比如:
function a(){
return 123;
}
a();
此时返回123。
function a(){
}
a();
此时返回underfind。
那么,我们在调用js里面的函数时候,其实不止这一种方式,常用的还用使用call或者apply方法也可以使函数执行,这个以后再说。除此之外,我们还可以通过 new的方式来调用函数,new在js里面其实是一种运算符,但凡函数是通过它来调用的,返回值就会发生变化。如果我们在函数中没有写返回值或者返回值写的不是对象类型的数据,那么这个函数都会返回一个空对象,如果我们写的返回值是一个对象,那么则返回我们写的对象。所以只要是通过new来调用函数,返回值就变成了对象。
js也充分利用了这一点,来模拟传统的面向对象,我们来看一个例子:
function Obj(){
this.name='小红';
this.age='24';
}
var poeple = new Obj();
根据我们上面说的,当我们使用new去调用函数时候,返回对象,因此我们可以得知people其实就是一个对象了。我们看到上面的代码中this.name='小红',this.age='24',这个this其实是什么呢?其实这个this就是我们返回的对象,也就是说this就是people,如果不能理解,只需记住,这是js的特点。我们接着看:
function Obj(){
this.name='小红';
this.age='24';
}
var poeple = new Obj();
alert(people.name);
alert(people.age);
运行上述代码以后,分别弹出了小红和24,这更加确切的说明this就是people.
但是这个this也不一定只是people,确切的说这个this是谁具体要看是谁在调用这个函数,看例子:
function Obj(){
this.name='小红';
this.age='24';
}
Obj();
当我这样去调用的时候,这个this指向的是谁呢?其实js是运行在浏览器中的,浏览器中有一个顶层对象叫做window,所有的变量和函数其实都是挂在他下面的,看例子:
Obj();
window.Obj();
这两种写法的效果是一样的,此时没有通过new来调用,其实就是一个普通的函数,而这个函数的调用者是window,因此这个this指向window.
所以说this的指向不是固定的,要看具体的调用方式以及是谁在调用。
我们一般把这种用来返回的对象的函数称作构造函数,他的作用就是用来创建对象的,一般为了区分构造函数与普通函数的区别,构造函数的首字母会大写。我早期学习的时候,就把这里的构造函数与其他语言里的class弄混淆了,其实他们是不同的东西。
第二个就是js的面向对象同样有继承的功能,只是它的继承与传统的继承方式也不一样,我个人认为也是一种模拟。首先说明一件事情,在js里面所有的对象都有一个叫做__proto__的属性,所有的函数都有__proto_的属性和prototype的属性,prototype属性对应的值是一个对象,这个对象可以保存很多东西的,中文名称叫做原型对象,看例子:
function Obj(){
this.name='小红';
this.age='24';
}
Obj.prototype.job='老师';
var poeple = new Obj();
alert(people.job);// 弹出 老师
刚才已经说过,此时的people就是一个对象,而Obj是一个函数,people是Obj的一个实例对象,他们之间肯定是有关系的,既然people是一个对象,那么他肯定有_proto_属性,这个属性其实指向了Obj的prototype,再详细说一下,people的__proto__保存的是一个地址,这个地址指向的是people的构造函数Obj的prototype属性。所以程序运行到people.job的时候,people这个对象在自己的属性里面开始寻找job这个东西,但是木有找到,于是接下来他就找到了自己的__proto__,顺着里面的地址找到了Obj.prototype,在这里发现了job,然后呢,他就把job的值给弹了出来。这一连串的动作专业术语叫做原型链查找,那为什么要说这个呢,主要是因为js的继承有一种方式就叫做原型继承。那上面已经把对象和构造函数的在原型方面的联系说清楚了。那么接下来我们就说一下js的原型继承,看例子:
function a(){
this.name='小红';
this.age='24';
}
function b(){
this.job='小红';
this.sex='男';
}
b.prototype=new a();
var c = new b();
alert(c.name);//小红
以上代码,做了一个功能,把b的原型对象修改成了a的实例对象,这时b的实例对象去访问name属性时候,首先在自身查找,没有发现,于是去他的构造函数b的原型里面去查找,而此时b的原型就是一个a的实例对象,a的实例对象当然有name和age属性了,因此就访问到了。这种方式成为原型继承,有一个小问题,就是这样直接把对象赋值给prototype,修改了prototype里面的constructer属性,constructer属性后面再说。
除了原型继承以外,还有一些方式也可以实现继承,最常用的就是call和apply方法,解释这个问题还需要了解另外一个特性,我们上面已经看到了,call方法可以用来调用函数,其实他的功能不止于此,最核心的功能就是改变this指向,我们来看例子:
此时,对象c拥有 name age self三个属性,前面两个就是继承下来的了。
其实,真实的编写过程,往往把上述两种继承方式同时使用,当然还有一些其他的继承方式,大家可以自己去网上查查。
这里说一下,上面那种原型继承法有一点点问题,直接把对象赋值给原型会导致原型里面的constructor出现错误,这个constructor实际上用来保存对象的构造函数的,也就是说一个对象是由那个构造函数实例化而成的,那么这个constructor就代表那个构造函数。举例:
function a(){
this.name='小红';
this.age='24';
}
var b = new a();
alert(a.constructor); // 打印出来的就是整个函数
如果直接把对象赋值给原型,这个constructor值就会被修改,所以,为了保险起见,很多人都会手动加上一句 a.prototype.constructor = a;
这里没有介绍更多的面向对象的东西,写的过程中也有遇到疑惑的,如果有错误的话,请大家多多指教!
javascript 特殊的面向对象以及继承详解(入门篇)的更多相关文章
- Redis详解入门篇
Redis详解入门篇 [本教程目录] 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 – 简介 ...
- Redis详解入门篇(转载)
Redis详解入门篇(转载) [本教程目录] 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 ...
- JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)
面向对象编程: 面向:以什么为主,基于什么模式 对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式 编程:使用代码解决需求 面向过程编程: 按照我们分析好的步骤,按步 ...
- 「MoreThanJava」Day 5:面向对象进阶——继承详解
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- [原创]JavaScript继承详解
原文链接:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html 面向对象与基于对象 几乎每个开发人员都有面向对象语言(比如C++. ...
- Kotlin——从无到有系列之中级篇(四):面向对象的特征与类(class)继承详解
如果您对Kotlin很有兴趣,或者很想学好这门语言,可以关注我的掘金,或者进入我的QQ群大家一起学习.进步. 欢迎各位大佬进群共同研究.探索 QQ群号:497071402 进入正题 在前面的章节中,详 ...
- JavaScript进阶知识点——函数和对象详解
JavaScript进阶知识点--函数和对象详解 我们在上期内容中学习了JavaScript的基本知识点,今天让我们更加深入地了解JavaScript JavaScript函数 JavaScript函 ...
- 转: javascript模块加载框架seajs详解
javascript模块加载框架seajs详解 SeaJS是一个遵循commonJS规范的javascript模块加载框架,可以实现javascript的模块化开发和模块化加载(模块可按需加载或全部加 ...
- 「万字图文」史上最姨母级Java继承详解
摘要:继承是面向对象软件技术中的一个概念.它使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用. 本文分享自华为云社区<「万字图文」史上最姨母级Java继承详解丨[奔跑吧!JAVA] ...
随机推荐
- XAMPP禁止目录浏览的方法
XAMPP是目前比较流行Web服务器套件,集成了Apache.MySQL.PHP.PERL.FTP等各种软件包.但是细心的人可以发现,XAMPP安装完成后,默认是可以目录浏览的,这有些不安全.如果需要 ...
- 使用nodejs搭建api的mock服务
1. 介绍 公司的业务开发都是静态页面,开发前期总是避免不了获取api的问题.在vue中有一些mockjs的方案,方案都是注入性质的,和最终部署总是有差别,而且业务大部分还在zepto下,很难找到合适 ...
- java-redis初探
一.Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的 ...
- $.ajax的一些坑啊
1.如果发送ajax返回的数据为json务必设置其 Content-Type:application/json;charset=UTF-8 不然会导致其success:function(data)中的 ...
- 浅谈session,cookie,sessionStorage,localStorage的区别及应用场景
浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和session cookie和session都是用来跟踪浏览器 ...
- MySQL如何正确查询字段为NULL的字段
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...
- 手把手教你在Ubuntu上分别安装Nginx、PHP和Mysql
手把手教你在Ubuntu上分别安装Nginx.PHP和Mysql
- AppCompatActivity 去掉标题栏和EditText弹出软键盘遮住输入框问题
1. AppCompatActivity去掉标题栏 此处除掉标题栏,需要注意一点,AppCompactActivity是继承自Activity.然而,AppCompactActivity据查看网上资料 ...
- sqlalchemy和flask-sqlalchemy几种分页操作
sqlalchemy中使用query查询,而flask-sqlalchemy中使用basequery查询,他们是子类与父类的关系 假设 page_index=1,page_size=10:所有分页查询 ...
- Android开发之Android Context Menu
1 Creatinga上下文菜单, Todefine上下文菜单的外观和行为,推翻youractivity的上下文菜单回滚方法,onCreateContextMenu()和onContextItemSe ...