JS学习日记--面向对象
一、js面向对象
1.什么是面向对象
面向对象编程(OOP)是一种计算机编程架构,他将真实世界的各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟
2.面向对象的目的
- 重用性:针对相同的功能可以重复的使用程序
- 灵活性:针对差异性的功能做出适配与调整
- 扩展性:针对功能的变化做出添加或删除的改进
3.面向对象的特性
- 封装性:封装是一种信息隐蔽技术,使得用户只能见到用户的外特性,而对象的内特性对用户是隐蔽的,封装的目的在于把对象的设计者和对象的使用者分开,使用者不必知晓实现的细节,只需用设计者提供的消息来访问该对象
- 继承性:复用一些原有的功能,同时可修改和扩充
- 多态性:对象根据所接收的消息而做出动作,同一消息为不同的对象接收时可产生完全不同的行动
4.面向对象的组成
- 属性:描述一种状态
- 方法:描述一种行为
- 程序中变量就是属性,函数就是方法
5.创建面向对象程序
在面向对象编程中,是通过“类”来创建对象的,类相当于模具。根据传递的数据来创建对象,并且可以重复的创建对象
在ES6之前的JavaScript中,是没有类的概念的,不过可以利用构造哈数来代替类进行创建对象
构造函数跟普通的函数并没有太大区别,知识调用的时候需要通过new关键字来调用,构造哈数中的this会指向创建出来的对象,并且具有隐式返回
示例代码:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><script type="text/javascript">function fun(name){this.name=name;this.showName=function(){console.log(this.name);}}var obj=new fun('hi');var obj1=new fun('hello');obj.showName();obj1.showName();</script></head><body></body>
</html>
二、object对象详解
1.对象的引用
- 类型比较方式:对象比较时,值跟引用地址都相同时才相等
var obj1={};var obj2={};console.log(obj1==obj2);
输出为:false
- 类型赋值方式:对象赋值时,值跟引用地址都进行赋值操作
var obj={name:'hello'}var obj2=obj;obj2.name='hi';console.log(obj.name)
输出为:hi
赋值时把obj的地址也赋给了obj2
- 浅拷贝与深拷贝:实现对对象的复制操作
浅拷贝:
var obj={name:'hello'}var obj2=copy(obj);function copy(obj){//浅拷贝var result={};for(var attr in obj){result[attr]=obj[attr];}return result;}obj2.name='hi';console.log(obj.name) ;
通过这个就可以只实现对象值得赋值而不会改变原有对象,不过如果对象的属性也是一个对象,就需要深拷贝
利用递归进行深拷贝:
var obj={name:{age:20}}var obj2=copy(obj);function copy(obj){//深拷贝var result={};for(var attr in obj){if(typeof obj[attr]=='object'){result[attr]=copy(obj[attr]);//递归}else{result[attr]=obj[attr];}}return result;}obj2.name.age=30;console.log(obj.name.age) ;
2.原型与原型链
- 原型:
在构造函数下面有一个prototype属性叫做原型,构造函数+原型整体也是一个对象叫做原型对象,在原型对象下面可以添加属性和方法 - 共享:
原型对象下的属性和方法,可供多个对象进行共享访问,这样就可以节省内存消耗(因为这样用的是一个地址,而上面咱们写的,每一个对象的方法都是不同的地址)
function Foo(name){this.name=name;}Foo.prototype.showName=function(){console.log(this.name)}var obj=new Foo('hello');var obj2=new Foo('hi');console.log(obj.showName==obj2.showName);
输出结果:true
证明用的是同一个地址
- 原型链:
为什么创建出来的对象可以访问到原型对象下面的属性和方法呢?这是通过哦原型链进行查找的。原型链即:连接对象与原型对象之间的纽带就是原型链
【注】:原型链最外层是Object.prototype,可以通过控制台查看
3.面相对象相关语法
- constructor:原型对象下唯一默认自带的属性,用于查看对象的构造函数
- instanceof:左边是实例对象,右边是构造函数,他会检查右边构造函数的原型对象,是否在左边对象的原型链上
- in与for…in:in运算返回一个布尔值,表示一个对象是否具有某个属性。for…in循环可获得对象所有可枚举属性
示例代码:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>相关语法</title><script type="text/javascript">/* function Foo(){}//Foo.prototype.constructor=Foo; Foo.prototype={constructor:FooshowName:function(){}};var obj=new Foo();console.log(obj.constructor);//Foo(){}*//* function Foo(){}var obj=new Foo();console.log(obj instanceof Foo);//true*/function Foo(){this.name='hello'}var obj=new Foo();console.log('name' in obj);//trueconsole.log('age' in obj);//false</script></head><body></body>
</html>
4.系统对象与包装对象
- 系统对象:JavaScript语言本身就是基于面向对象的程序,最大的对象为window对象。内置了很多系统对象,如:数组、时间、正则等。
可以自行打印一下window对象,可以看到很对内置的对象
仔细想想其实JS本身就是一个很大的面向对象的程序,包括我们平时用的数组之类的都是一个对象,有push,sort等方法
首先,假如我们进行了这样的操作
<script type="text/javascript">var arr=[1,2,3];Array.prototype.push=function(){}arr.push(4,5,6)console.log(arr);</script></head>
这样push操作就会失败,因为我们重写了数组对象的push方法,也验证了上面说的,数组就是一个对象
接下来咱们自己实现一个push方法:
<script type="text/javascript">var arr=[1,2,3];Array.prototype.push=function(){for(var i=0;i<arguments.length;i++){this[this.length]=arguments[i];}return this.length;}arr.push(4,5,6)console.log(arr);</script></head>
- 包装对象:基本类型如:字符串、数字、布尔值等都具备对应的包装对象。可以通过包装对象来获取提供的属性与方法
如:字符串其实就是new String创造出来的包装对象
当我们用字符串的一下方法比如 str.trim()时,他其实是先找到new String()对象,再找到trim方法,他写在原型链上共享给了str
5.继承与多态
(1)继承方式
拷贝继承:
<script type="text/javascript">function Foo(){//父类this.name='hello';}Foo.prototype.showName=function(){console.log(this.name);};function Bar(){//子类Foo.call(this);this.age=20}extend(Bar,Foo);Bar.prototype.showAge=function(){console.log(this.age);}function extend(subs,sups){for (var attr in sups.prototype) {subs.prototype[attr]=sups.prototype[attr];}}var obj1=new Foo();var obj2=new Bar();console.log(obj1);console.log(obj2);</script>
类式继承:
<script type="text/javascript">function Foo(){//父类this.name='hello';}Foo.prototype.showName=function(){console.log(this.name);};function Bar(){//子类Foo.call(this);//继承属性还是用callthis.age=20}extend(Bar,Foo);Bar.prototype.showAge=function(){console.log(this.age);}/*function extend(subs,sups){for (var attr in sups.prototype) {subs.prototype[attr]=sups.prototype[attr];}}*/function extend(subs,sups){//不直接用原型链继承而是通过新建一个函数实现只继承方法//否则创造多个对象之后可能就会影响到这个属性var F=function(){};F.prototype=sups.prototype;subs.prototype=new F();subs.prototype.constructor=subs;//修改了原型之后要把,constructor修正一下}var obj1=new Foo();var obj2=new Bar();console.log(obj1);console.log(obj2);</script>
(2)多态
重写继承的方法
就是简单的重写一下方法,例如上面的例子,咱们把Bar的showName方法重写一下
Bar.prototype.showName=function(){console.log('aaa'+this.name); }
接下来调用Bar.showName()就会输出aaahello
JS学习日记--面向对象相关推荐
- 我的 Vue.js 学习日记 (七) - 事件与修饰符
上节回顾 上节写了一个v-for与table的简单互动,脑子里回忆一下,嗯 ~ 还是回去再看一遍吧... 本节目标 今天看一下事件与修饰符,并且把有疑惑的地方敲一遍,亲眼看一下输出结果.由于时间有限, ...
- Vue.js学习日记03
Vue.js样式绑定 Vue.js class class 与 style 是 HTML 元素的属性,用于设置元素的样式 class 属性绑定 为 v-bind:class 设置一个对象,从而动态的切 ...
- Node.js学习日记3
1.__filename 解析:__filename表示当前正在执行的脚本的文件名.它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同.如果在模块中,返回的值是模块文件的路径. 2 ...
- JS学习日记(二)字符与对象
一.字符串 一.定义 JS中字符串与C类似,用单引号或双引号表示字符串,在单/双内部引用单/双要加反斜杠\ 'Did she say \'Hello\'?' // "Did she say ...
- js学习日记-Bingo Card
用循环进行重复操作 例做一个Bingo Card html部分 ... <table> <tr> <td id="s0"> </td> ...
- js学习日记-new Object和Object.create到底干了啥
function Car () {this.color = "red"; } Car.prototype.sayHi=function(){console.log('你好') }v ...
- JS学习日记--正则基础语法
一.正则表达式 正则表达式是由普通字符及特殊字符组成的对字符串进行过滤的逻辑公式 创建方式 字符量的方式: var reg = /abc/: 构造函数 var reg = new RegExp(&qu ...
- 【前端学习日记】利用reveal.js把实验报告做成一个简单的幻灯片
一.整体效果 把电磁场的实验报告做成网页PPT,原文是这里:<[电磁场实验作业]有限差分法(FDM)求解静电场电位分布_轩辕衍的博客-CSDN博客> 二.核心代码讲解 0.创建页面 第一篇 ...
- 十五的学习日记20160926-你不知道的JS笔记/
十五的学习日记20160926 JavaScript 一个用于检测正负值的函数,可以用它辨别-0值. 我觉得挺好用,以后可以写到自己的工具库里. //函数:检查传入参数是否为正数.Number=> ...
最新文章
- 阻塞队列(1)--ArrayBlockingQueue底层实现
- SSM整合(2): spring 与 mybatis 整合
- 【MM模块】Invoice Verification in the Background 后台发票校验
- laravel excel迁移到lumen
- CodeForces - 1486E Paired Payment(分层图最短路)
- VMware虚拟机与宿主无法复制的解决办法
- 201312-5 I’m stuck!
- C语言解决迭代递推问题
- 计算机mac地址设置路由器,MAC地址修改教程
- 国内各类有用搜索网站汇总
- LeetCode #1056. Confusing Number
- JavaScript 实现页面内时间实时倒计时 计时器内附完整文件欢迎调用(可用于抢购倒计时,记录恋爱纪念日总时长等)输出对应的天数小时分钟秒数
- 华为鸿蒙系统穿戴app,华为应该如何盘活鸿蒙系统?
- STL浅析 RB-tree(红黑树)
- dpabi viewer使用
- 有一种情愫,它不属于暧昧
- python测速程序_利用Python对网站进行测速
- android开源app简书,参考APP, 开发, 发布
- Goslate: Free Google Translate API
- 163 新闻页面网络爬虫简单抓取数据