JavaScript面向对象

今天我们来介绍一下JavaScript的面向对象部分,那么学过js的朋友应该都知道,关于js面向对象部分是有一点乱的,并没有像java,python之类的有一些比较明确的规范,当然,在之后的ES6的部分还是做了一些完善。

创建对象的几种方式

js不同于强类型语言,关于创建对象它有以下几种方式:

一、字面量方式创建对象

字面量创建对象方式实际上就是实例化创建,代码如下:

var obj = {name : '张三',age : 20,sex : '男',run : function(){console.log('我正在运动')}}obj.run();console.log(obj);//不需要使用new,因为它本身便是实力化对象//这种方式创建对象时较为繁琐,当需要实例的对象过多时不适用
二、自定义构造函数创建对象
function obj(name,age){this.name = name;this.age = age;this.run = function (){console.log('我正在运动');}}var a = new obj("张三",'20');a.run();//'我正在运动'console.log(a.name);//张三console.log(a.age);//20
三、工厂模式创建对象

工厂方式实际上是利用了js原生的Object对象

function Person(name,age){var obj = new Object();obj.name = name;obj.age = age;obj.run = function (){console.log('我正在运动');}return obj;//返回该对象}var a = new Person("张三",'20');//创建新的对象a.run();//‘我正在运动’console.log(a.name);//张三console.log(a.age);//20
四、 使用ES6规范创建对象

关于ES6的创建对象的语法格式就和java之类的强类型语言相似了,或者说js进行了一个模仿,代码格式如下:

class Person{constructor (name,age){this.name = name;//属性this.age = age;}//构造函数run(){//方法console.log(this.name + '正在运动')}}var a = new Person('张三',20);//实例化对象console.log(a.age);//20console.log(a.name);//张三a.run();//张三正在运动

js在ES6面向对象当中引入了class关键字,用来进行关于类的定义,那么constructor里面是构造函数的书写,相信大家都理解,这里不过多说,关于run方法的书写,这里是es6语法当中的一种字面量的简要写法。

当然除了以上几种方式,还有些混合模式之类的,不常用也就不做解释。

对象的继承

对于面向对象的语言来说,面向对象的三个部分:封装,继承,多态是必不可少的。但是在js当中并不具备多态这个特性,它并不像java等强类型语言具有方法的重载和重写等功能,因此并不具备多态,因此它是基于面向对象的语言,但并不面向对象,这一点大家要理解清楚。

那么接下来我们讲解一下在js中关于继承的几种方式:

一、通过原型链实现继承
function Animal(age){this.age = age;this.eat = function(){console.log('吃点什么东西吧')}}function CatClass(name,color){this.name = name;this.color = color;this.sleep = function (){console.log('睡一觉吧,太累了')}}CatClass.prototype = new Animal(18);//对原型链进行赋值,更改var b = new CatClass('小黑','black');b.sleep();//睡一觉吧,太累了b.eat();//吃点什么东西吧console.log(b.age)//18

大家看到了,上面的代码就是通过对原型链的更改实现了,使用b对象调用eat()方法,b对象是CatClass创建出来的,却调用了Animal当中的eat()方法,因此实现了继承。原型链赋值那里需要注意,赋的值是一个新对象。

但是这个方式会有一个问题,因为他们的原型链指向的是同一个内存地址,所以如果父亲和儿子有相同的引用数据类型属性和方法,对其中的一个进行更改,那么另一个也会进行相应的更改,如果我们需要父亲儿子做不一样的事情,那么我们需要做一个小小的改动。就是利用一个介质或者说一个变量来对这个原型链进行一个保存,然后再将这个变量赋值给另一个原型链,那么这样他们就会互不干扰。

二、使用call或者apply改变this指向实现继承
function Father (name,age){this.name = name;this.age = age;this.introduce = function (){console.log('我是父亲我现在'+this.age+'岁');}}function Son (name,age){Father.call(this,name,age);//改变this指向}var father = new Father();var son = new Son('张三',48);//注意这边,如果父亲的方法中有参数的话,那么改变了this指向以后就变成了儿子的方法,那么就需要儿子接收参数,再通过call传递给父亲然后调用这个方法son.introduce();//儿子调用父亲的introduce方法

那么apply方法和call方法的不同就只是参数的不同,需要通过[ ]数组的形式来传递参数

function Son (name,age){Father.apply(this,[name,age]);
}

其实说到这里,还有一种方法bind,使用方法参照call,但是由于占内存和浏览器兼容性的问题,不常用。因此我们记住call和apply就完全够用了。
虽然这种方式解决了引用数据类型的关联改变,但是使用call或者apply这样的方式会破坏代码的复用,降低效率

三、组合方式实现继承(利用原型链加上call或者apply)

在上述中的一、二两种方式我们了解过后都有一些缺陷,那么我们现在使用组合办法解决这些缺陷,实现私有属性方法不可以更改,共有属性方法都可以访问,代码示例如下:

 function Father (name,age){this.name = name;this.age = age;this.list = [1,2,3]}Father.prototype.introduce = function (){console.log('我是父亲我现在'+this.age+'岁');}//在prototype中设置公有方法function Son (name,age){Father.call(this,name,age);//改变this指向}Son.prototype = new Father();//原型链继承Son.prototype.constructor = Son;//因为上一行代码实现原型链继承更改了构造函数,所以需要将父亲的改成自己的var son = new Son('张三',48);//注意这边,如果父亲的方法中有参数的话,那么改变了this指向以后就变成了儿子的方法,那么就需要儿子接收参数,再通过call传递给父亲然后调用这个方法son.introduce();//儿子调用父亲的introduce方法son.list.push(4);console.log(son.list);var son1 = new Son();console.log(son1.list);

结果如下:

这也是组合类型的优势,也是比较完善的继承,也是比较常用的方法。

四、ES6利用extends继承

如果学过java的朋友们那就会觉得很熟悉了,没错js中ES6的使用方式和java当中的继承相同,详细代码如下:

class Father{constructor (name,age){this.name = name;//属性this.age = age;}//构造函数introduce(){//方法console.log(this.name + '正在运动')}}
class Son extends Father{constructor(name,age) {super();//super 关键字用于访问父对象上的函数。当有了参数以后会访问父亲的constructor,并且返回当前thisthis.name = name;//属性this.age = age;}
}
var son = new Son('父亲',48);
// console.log(son);
son.introduce();//儿子调用父亲的introduce方法

那么关于js面向对象我们就先说到这里。
若有错误或缺陷请评论指出,将及时修改。

关于JavaScript面向对象相关推荐

  1. JavaScript面向对象编程

    自从有了Ajax这个概念,JavaScript作为Ajax的利器,其作用一路飙升.JavaScript最基本的使用,以及语法.浏览器对象等等东东在这里就不累赘了.把主要篇幅放在如何实现JavaScri ...

  2. 《JavaScript面向对象精要》读书笔记

    JavaScript(ES5)的面向对象精要 标签: JavaScript 面向对象 读书笔记 2016年1月16日-17日两天看完了<JavaScript面向对象精要>(参加异步社区的活 ...

  3. javascript面向对象系列第一篇——构造函数和原型对象

    前面的话 一般地,javascript使用构造函数和原型对象来进行面向对象编程,它们的表现与其他面向对象编程语言中的类相似又不同.本文将详细介绍如何用构造函数和原型对象来创建对象 构造函数 构造函数是 ...

  4. 用JSON和Javscript的prototype来构建完善的Javascript面向对象表示法

    [原文地址:http://www.cnblogs.com/robinhood/archive/2006/11/16/515412.html] 上次发贴没能很好的总结Javascrip编写类的方法,这次 ...

  5. 《JavaScript面向对象精要》——1.8 原始封装类型

    本节书摘来自异步社区<JavaScript面向对象精要>一书中的第1章,第1.8节,作者:[美]Nicholas C. Zakas 译者: 胡世杰 更多章节内容可以访问云栖社区" ...

  6. 《JavaScript面向对象编程指南》——第1章 引言1.1 回顾历史

    本节书摘来自异步社区<JavaScript面向对象编程指南>一书中的第1章,第1.1节,作者: [加]Stoyan Stefanov 译者: 凌杰 更多章节内容可以访问云栖社区" ...

  7. 《JavaScript面向对象编程指南》——1.3 分析现状

    本节书摘来自异步社区<JavaScript面向对象编程指南>一书中的第1章,第1.3节,作者: [加]Stoyan Stefanov 译者: 凌杰 更多章节内容可以访问云栖社区" ...

  8. JavaScript面向对象及原型 及setTimeout

    JavaScript面向对象 最笨的写法: function Foo(n) {     this.name = n;     this.sayName = function() {         c ...

  9. JavaScript面向对象的支持(7)

    ================================================================================ Qomolangma OpenProj ...

  10. (二)Javascript面向对象编程:构造函数的继承

    Javascript面向对象编程:构造函数的继承 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承&q ...

最新文章

  1. 老年痴呆 数字化_设计老年人愉快数字体验的5条原则
  2. Sublime使用的插件和快捷键
  3. SQL Story摘录(七)————触摸NULL值
  4. Android RecycleView ScrollBy不生效
  5. Windows系统盘符错乱导致桌面无法加载。
  6. Linux上安装php
  7. 将.NET dll注册到GAC(Global Assembly Cache)中
  8. Xamarin Android Webview中JS调用App中的C#方法
  9. Ext.net中的MessageBox的简单应用
  10. 他们在大学本科实现童年梦想!自研火箭,飞向外太空,创造人类新纪录
  11. 使用ImageView引起Missing contentDescription attribute on image的问题
  12. SameMovie HBOMax Video Downloader for Mac如何在 Mac 上下载 HBO Max 视频?
  13. xss测试工具xsstrike(基于python3)
  14. 2022-2027年中国电动汽车充电站及充电桩行业市场深度分析及投资战略规划报告
  15. html遇到英文单词整体换行,HTML在table中如何强制单词换行
  16. requests+xpath之贴吧图片爬取
  17. UFS开发板代码分析
  18. 高效实现斐波那契数列(Fibonacci数列)
  19. 【如何从外观上区分网线的五类线、超五类线和六类线?】
  20. 如何用计算机制作动态图,电脑怎么制作gif动态图

热门文章

  1. 我所知道的专业搜索引擎
  2. Python爬虫入门-fiddler抓取手机新闻评论
  3. MySQL系列:ES数据同步
  4. C# 高并发获取唯一ID算法
  5. 云主机磁盘I/O %util飙高排查
  6. Vue——v-if控制元素是否显示
  7. 组网技术:ADSL+无线路由器组网实例图解(组图)
  8. 2017年度全球一级市场“投资龙虎榜”发布 | 钛媒体Pro独家
  9. QTimer计时速度不断加快问题和QT中show函数失效问题的思考和处理
  10. python定时开关机的代码_python实现Windows电脑定时关机