原文链接:http://www.hansmkiii.com/2018/07/06/javascript-node-1/

" 面向对象、原型、继承 "

1、面向对象

1.1 什么是面向对象程序设计

为了了解 面向对象面向过程 的区别,我们先看案例1。

案例1:一辆汽车以60km/h,在一条长度1200km的公路上行驶,求其行驶完全程需要的时间。

/* 面向过程 */
var time = 1200 / 60; // 计算汽车行驶时间
console.log(time); // 打印结果
/* 面向对象 */
// 创建公路对象
var road = {long: 1200 // 公路长度
};// 创建小汽车对象
var car = {speed: 60, // 汽车速度road: road, // 汽车在公路上行驶,与公路对象关联(road已声明)run: function(){ // 汽车行驶的方法,返回行驶速度return this.road.long / this.speed;}
}var r = car.run(); // 执行汽车行驶的方法,返回行驶速度
console.log(r); // 打印结果(30)

虽然看上去面向对象比面向过程要复杂了很多,但是如果考虑到以后可能会改变某个变量(公路长度或汽车行驶速度),面向过程需要修改运算过程中的值,而面向对象只需要在执行运算方法之前通过car.speed = 40修改 car 对象的 speed 属性即可,可以有效避免修改错误和修改多处。

当程序复杂程度到达一定的量级,面向对象可以提高程序的可维护性。

如果后面我们的需求改变了,依旧需要汽车对象,但是要返回汽车的颜色。
如果是面向过程开发,我们需要删除掉面向过程的所有代码,重新写代码返回汽车的颜色。而面向对象则不需要删除原来定义的对象,只需要给 car 对象增加一个 color 属性,扩展 car 对象。

所以,面向对象程序设计的优势有:

  1. 提高代码的可维护性
  2. 提高代码的可扩展性

1.2 面向对象的方式操作DOM

HTML

<div>111</div>
<div>222</div>
<div>333</div>
<div>444</div>

JS

// 给div添加背景颜色
// 面向过程
var divs = document.getElementsByTagName('div');
for (var i=0; i<divs.length; i++) {divs[i].style.backgroundColor = 'red';
}// 面向对象
var domOpr = {getDiv: function(){var divs = document.getElementsByTagName('div');return divs;},setStyle: function(){var divs = this.getDiv()for (var i=0; i<divs.length; i++) {divs[i].style.backgroundColor = 'red';}}
}
domOpr.setStyle();

如果多处需要相同的功能,面向对象的方法可以提高代码的复用性


2、继承

传统的面向对象语言,继承是 之间的关系。而JS中,由于没有 的概念。所以是 对象对象 之间的关系。

定义:在JS中,继承就是指使一个对象有权去访问另一个对象的能力。
比如:对象A能继承对象B的成员(属性和方法),那么,对象A就继承于对象B。

2.1 原型继承

原型

定义:原型就是指构造函数的prototype属性所引用的对象。
目的:解决同类对象数据共享问题。

示例:

// 创建构造函数 Person
function Person(name, age){ this.name = name;this.age = age;this.say = function(){console.log('hello!')}
}
// 创建 Person 的实例对象
var p1 = new Person('张三', 19);
var p2 = new Person('李四', 20);
// Person.prototype 就是对象 p1 的原型
// p1.__proto__ 也是 p1 的原型
console.log(Person.prototype === p1.__proto__); // true

此时,p1和p2都有继承了构造函数 Person 的 say 属性,在控制台打印查看:

p1.say(); // hello!
p2.say(); // hello!

这是 构造函数继承,那么 p1 的 say 和 p2 的 say 是不是同一个方法呢?

// 打印查看
console.log(p1.say === p2.say); // false

查看结果发现两个 say 方法并不是同一个,所以在创建实例对象的时候开辟了两块内存分别存放了 p1.say 和 p2.say,这就导致了内存的浪费,所以我们需要通过原型共享数据来解决这个问题。

// 创建构造函数 Person
function Person(name, age){ this.name = name;this.age = age;
}
// 创建 Person 的实例对象
var p1 = new Person('张三', 19);
var p2 = new Person('李四', 20);
// Person.prototype 就是对象 p1 的原型
// p1.__proto__ 也是 p1 的原型
// 在原型上创建一个 say 属性
Person.prototype.say = function(){console.log('hello!');
}
// 运行 p1.say 和 p2.say,并对比是否为同一个方法。
p1.say(); // hello!
p2.say(); // hello!
console.log(p1.say === p2.say); // true

如此便通过原型继承实现了数据共享。

构造函数中可以显式的指定return语句,但是如果返回的数据类型为简单数据类型,或者null undefined值都会被忽略,依旧返回的是构造函数的实例对象

2.2 类式继承

类式继承通过call(this, ... , ...)apply(this, arguments)方法改变this指向实现继承。

// 创建 Person 构造函数
function Person(name, age) {this.name = name;this.age = age;
}
// 创建 Student 构造函数
function Student(name, age, id){this.name = name;this.age = age;this.id = id;
}

Student对象是 Person 对象的一个分支,可以继承Person的属性。
所以Student 属性可以这样写:

function Student(name, age, id){Person.call(this, name, age);this.id = id;
}var s = new Student('张三','20','123456789');
console.log(s); // {name: "张三", age: "20", id: "123456789"}

或者

function Student(name, age, id){Person.apply(this, arguments); // arguments 是一个数组 也可以写成 [name, age]this.id = id;
}var s = new Student('张三','20','123456789');
console.log(s); // {name: "张三", age: "20", id: "123456789"}

2.3 组合继承

通过前面对 原型继承类式继承 的了解,我们发现 原型继承 用于继承静态数据, 类式继承 用于继承动态参数,所以我们有时候需要同时使用 原型继承类式继承,也就是 组合继承

function Person(name, age) {this.name = name;this.age = age;
}
// 类式继承
function Student(name, age, id){Person.call(this, name, age);this.id = id;
}
// 原型继承
Student.prototype.class = function(){console.log('English');
}
var s = new Student('张三', 20, '123456');
s.class();

2.4 extend方法

var a = {name: 'g'
};var b = {print: function() {console.log('Hello,JS!')}
}
// 将 parent 对象上的成员赋值给 child
function extend(child, parent) {for (var pro in parent) {// child[pro] = parent[pro];// 缺点:会将parent对象的原型上的成员一同复制过来,所以需要先判断属性是否为parent私有的if (parent.hasOwnProperty(pro)){child[pro] = parent[pro];}}
}
extend(a,b);
a.print();

以上四种继承方式是开发过程中最常见的几种,具体应用场景视情况而定,甚至可以多个组合使用

【笔记】JavaScript高级篇——面向对象、原型、继承相关推荐

  1. JavaScript高级篇之Function对象

    JavaScript高级篇之Function对象 一: Function对象引入: Function对象是js的方法对象,可以用Function实例化出任何js方法对象. 例如: 1 <%@ p ...

  2. RabbitMQ学习笔记(高级篇)

    RabbitMQ学习笔记(高级篇) 文章目录 RabbitMQ学习笔记(高级篇) RabbitMQ的高级特性 消息的可靠投递 生产者确认 -- confirm确认模式 生产者确认 -- return确 ...

  3. 《Unity Shader入门精要》笔记:高级篇(3)以及扩展

    本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...

  4. JavaScript高级篇

    JavaScript高级篇 一 arguments: 1.在JavaScript中,每一个函数都包含一个arguments属性2.arguments属性是一个数组3.在函数调用时,将实参传入函数的ar ...

  5. 2、Spring Boot尚硅谷笔记整理高级篇-消息

    1.Spring Boot尚硅谷笔记整理高级篇-缓存 2.Spring Boot尚硅谷笔记整理高级篇-消息 3.Spring Boot尚硅谷笔记整理高级篇-检索 4.Spring Boot尚硅谷笔记整 ...

  6. JavaScript高级(面向对象)

    文章目录 1 面向对象编程介绍 1.2 面向过程编程 POP(Process-oriented programming) 1.3 面向对象编程 OOP (Object Oriented Program ...

  7. JavaScript高级之面向对象高级

    三.面向对象高级 此部分要求你对前方函数高级部分的1.原型与原型链比较熟悉,如果掌握不够好理解会相对困难 1.对象创建模式 Ⅰ-Object构造函数模式 方式一: Object构造函数模式 套路: 先 ...

  8. JavaScript中的面向对象--对象继承

    JavaScript高级程序设计第3版 p162 这里总结一下JavaScript中对象继承的方式,主要有原型链和借用构造函数模式,衍生的出来的有组合式继承.原型式继承.寄生式继承和寄生组合式继承.原 ...

  9. 读书笔记-JavaScript高级程序设计(1)

    1.组合继承 (JavaScript 中最常用的继承模式 ) (position: page168) (书中定义了两个变量名 SuperType   SubType  乍一看 感觉不太能区分,我将改为 ...

最新文章

  1. python数字类型转换函数_Python的数据类型转换函数
  2. 第21/24周 性能监控(PAL工具)
  3. 通过script标签实现跨域
  4. Java:十六进制转换成十进制
  5. 一篇文章带你搞定Python返回函数
  6. python中sklearn中的Imputer模块改动
  7. 使用Vs code上传github需要输入密码和用户名解决
  8. 如何查看系统启动时间-
  9. 只做两个龅牙门牙_孔子画像中的门牙格外突出,画师为何不给圣人开美颜?...
  10. win10打不开计算机配置似乎是正确的,Win10系统软件打不开提示“并行配置不正确”如何解决...
  11. 蜂鸣器干扰通讯_提高蜂鸣器响度和降低蜂鸣器及驱动电路干扰电源的电路的制作方法...
  12. QQ空间g_tk算法的JS脚本的获取和分析
  13. 【Fuzzy】模糊专家系统(1)
  14. 索尼展示基于MicroLED技术的16K显示屏:约780吋
  15. WLAN--什么是信道(Channel)
  16. 木马伪装“刷单任务” 劫持QQ语音暗中盗号
  17. html5 语音导航,TeleNav提供基于HTML5技术的浏览器级turn-by-turn语音导航服务
  18. 记一次失败的尝试--ubuntu下把笔记本无线网卡的驱动替换掉
  19. 阿里巴巴推动时尚零售智能化 FashionAI展示数字化零售新模式
  20. 如何修改百度地图上marker的icon地址

热门文章

  1. idea引入本地jar包及打包
  2. sunplus 8202v iop源代码阅读笔记——2
  3. 刘强东解读京东AI战略布局,沈南鹏高文杨强助阵谈AI机遇
  4. java基础:8.1 异常
  5. leetcode刷题笔记(3)(python)
  6. ActiveMQ - spring集成jms
  7. struts2中的值栈对象ValueStack
  8. mysql获取当前时间,前一天,后一天
  9. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)
  10. centos6.5 x86_64安装rsyslog + loganalyzer