浅谈面向对象的javascript几个特性

javascript中的thisnew

javascript是一门很灵活的语言,尤其是function。他即可以以面向过程的方式来用,比如:

function getName() {return '张三'
}
getName()

也可以以面向对象的方式来用,比如:

function User() {this.name = '张三'
}var user = new User()

javascript是如何实现面向对象编程的呢?他提供了new这个关健字,有了new就可以把对象进行实例化,比如:

function User(name, age){this.name = namethis.age = age
}
var zs = new User('zs', 20)
var ls = new User('ls', 30)

new出来的两个实例,会开辟两块新的内存区域,来保存这些数据,同时有指针指向对象User。所以就有instanceof这个运算符,这个运算符的意思就是:a是不是A的实例。比如上例:zs instanceof User的返回值是true
即然是面向对象的编程语言,那this也是不可或缺的。在javascript中,this永远指向的是他的调用者。要理解这句话,我们举几个例子:

例子1

function test(){this.name = 'zs'
}
test()

当执行完成之后,这个name会直接挂载到window下面,因为是这样执行的:winow.test()

例子2

var game = document.getElementById('game')
game.addEventListener('click', function () {setTimeout(function () {this.innerText = 'Clicked'}, 1000)
})

这个例子很简单,点击某个元素的时候,1秒后,让他里面的html改成Clicked,可是你发现这样不好使,就是因为this指向的问题,因为这里面的this也指向window了,所以你执行window.innerText会返回Clicked

例子3

function User(name) {this.name = namethis.getName = function () {console.log(this.name)}
}
var u = new User('zs')
u.getName()

这里面的this的指向没有问题,因为按照之前的原则,调用者是u,也就是User的实例,所以在方法getName中,this.name相当于u.name,所以打印出zs

prototype和__proto__

prototype

javascript是面向对象的语言,这个上面已经提过了,其他面向对象语言有一个必备我就是继承,很显然在ES6之前,没有extends这个关键字,那么,javascript就是利用prototype的原型链来实现继承。先记住这句话,我们一会会说到继承。prototype其实只是对象的一个属性,在Chrome控制台下,可以直接看出来,但是这个属性很特殊,这个属性下可以挂载任何的对象、方法、属性,而且挂载的东西可以反映到实例下对象上。说的比较绕,我们看个例子:

function User(name) {this.name = name
}
User.prototype.getName = function () {console.log(this.name)
}
var u = new User('zs')
u.getName()

我们在User.prototype上面挂载了getName的方法,在下面实例化User之后的u,就可以访问这个方法。
看到这,你可以有个疑问,既然是给实例化对象用的,那下面这种方式岂不是更好、更直观?

function User(name) {this.name = namethis.getName = function () {console.log(this.name)}
}
var u = new User('zs')
u.getName()

如果我们和Java语言进行对应,User相当是Classname相当于属性,getName相当于里面的方法,完美映射!可以这样有一个问题啊,就是太费内存了。因为每new一个对象,都会占用一块内存区域,这样User里面方法属性越多,那么每个实例化的对象都会对这些进行 深复制,那么占用的内存空间就越大。那么javascript是如何通过prototype来解决内存占用的问题的呢?这就需要引用__proto__

__proto__

定义:__proto__是存在于实例化后对象的一个属性,并且指向原对象的prototype属性
比如上例中的u.__proto__ === User.prototype返回的是true。可以在Chrome控制台下查看u.__proto__

你会发现,不对吧,User对象下也有__proto__啊。那是因为User也是Function的实例,不信你可以试一下User.__proto__ === Function.prototype的返回值。其实我们这样定义函数:function test(){}是一个语法糖的写法,全拼应该是这样:var test = new Function('alert(1)')

现在我们来解释为什么使用prototype能节省内存。不知道你有没有注意到上面一句代码u.__proto__ === User.prototype,我为什么要使用三等?因为三等号除了值、类型外,内存地址也必须是相等的,也就是说User不管实例化多少对象,他们的prototype只有一份,放在User里。客户端的浏览器环境不像服务器,内存还是比较紧张的,所以javascript通过这种方式,来解决内存占用问题。

继承

方式一:直接继承

先举个例子:

var Animal = function (name) {this.name = name
}
Animal.prototype.walk = function () {console.log('I can walk!')
}
Animal.prototype.getName = function () {console.log('My name is ' + this.name + '!')
}var Dog = function (name) {this.name = name
}
Dog.prototype = Animal.prototypevar d = new Dog('Tom')
d.getName()
d.walk()

我们建立一个父类Animal对象,建立一个子类Dog,我们想让Dog也有walk方法和getName方法,通过上面对prototype的了解,我们最先想到的是Dog.prototype = Animal.prototype,这样子类和父类的prototype相等,那子类就有父类所有方法喽,继承链条是这样的:d.__proto__ === Dog.prototype === Animal.prototype
这样很直观,但是也有一个比较严重的问题。我们在扩展Dog的时候,同时父类也会有对应的方法,这很显然是一个很严重的问题。

方式二:实例化继承

为了解决上面的问题,我们需要引入一个空函数,这个空函数做为桥梁,把子类和父类之间的连接切断。实现如下:

var F = function () {}
F.prototype = Animal.prototype
Dog.prototype = new F()Dog.prototype.say = function () {console.log('Say')
}
  • 为什么是Dog.prototype = new F()呢?因为这样即可以继承Animal的所有方法,他的原型链是这样的:
d.__proto__ --> Dog.prototype --> new F().__proto__

执行walk方法,F已经有了,所以就不会再找Animal

  • 新增加的方法又不影响父类,这句怎么讲?因实例化的对象没有prototype属性!所以不会影响

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/455591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Netty】ChannelHandler和ChannelPipeline

一、前言 前面学习了Netty的ByteBuf,接着学习ChannelHandler和ChannelPipeline。 二、ChannelHandler和ChannelPipeline 2.1 ChannelHandler 在ChannelPipeline中,ChannelHandler可以被链在一起处理用户逻辑。 1. Channel生命周期 Channel接口定义了一个…

自动驾驶安全驾驶规则_自动驾驶知识科普 自动驾驶汽车的七大核心技术

自动驾驶技术的本质是用机器视角去模拟人类驾驶员的行为,其技术框架可以分为三个环节:感知层、决策层 和执行层,具体涉及传感器、计算平台、算法、高精度地图、OS、HMI等 多个技术模块。目前自动驾驶L3商业化技术已经成熟,L4级/L5…

bupt summer training for 16 #3 ——构造

https://vjudge.net/contest/172464 后来补题发现这场做的可真他妈傻逼 A.签到傻逼题&#xff0c;自己分情况 1 #include <cstdio>2 #include <vector>3 #include <algorithm>4 5 using std::vector;6 using std::sort;7 8 typedef long long ll;9 10 int n…

python常用快捷键、写代码事半功倍_Pycharm常用快捷键总结及配置方法

工欲善其事必先利其器&#xff0c;Python开发利器Pycharm常用快捷键以及配置如下&#xff0c;相信有了这些快捷键&#xff0c;你的开发会事半功倍 一 常用快捷键 编辑类&#xff1a; Ctrl D 复制选定的区域或行 Ctrl Y 删除选定的行 Ctrl Alt L 代码格式化 Ctrl Alt O 优…

使用FFMPEG SDK解码流数据获得YUV数据及其大小

本文以H264视频流为例&#xff0c;讲解解码流数据的步骤。 为突出重点&#xff0c;本文只专注于讨论解码视频流数据&#xff0c;不涉及其它&#xff08;如开发环境的配置等&#xff09;。如果您需要这方面的信息&#xff0c;请和我联系。 准备变量 定义AVCodecContext。如果您…

关于Python3.7和Python3.6中元组类型数据内存存储问题

关于Python3.7和Python3.6中元组类型数据内存存储问题 小编最近发现了一个瑕疵 当定义一个元组类型的变量后,若在程序后面再定义一个元组变量,这两个元组的内容相同,那么在不同的版本中会出现不同的结果 在Python3.6版本中,解释器将在内存中开辟两个内存空间分别存储两个元组的…

shell 删除了hdfs 文件_从零开始学大数据(三) Shell操作HDFS文件系统-中

1、格式化[rootmaster sbin]# hdfs namenode -format2、命令hdfs dfsadmin查看(hdfs dfsadmin -report)[rootmaster ~]# hdfs dfsadmin -report安全模式#获取安全模式状态[rootmaster ~]# hdfs dfsadmin -safemode get#进入安全状态[rootmaster ~]# hdfs dfsadmin -safemode en…

计算机硬件

计算机硬件 一、为什么要学习计算机基础 程序员编程的本质就是让计算机去工作&#xff0c;而编程语言就是程序员与计算机沟通的介质。程序员要想让计算机工作&#xff0c;就要知道计算机能干什么、是怎么样的一个完成过程&#xff0c;这也是我们必须学习计算机基础的原因。 …

铁路售票系统_铁路资讯:复兴号动车、智能京张高铁…中国最高端铁路装备看这里...

今天上午&#xff0c;两年一度的中国国际现代化铁路技术装备展在京开展&#xff0c;会期3天&#xff0c;将集中展示路网建设、客货运输、经营管理、工程建造、技术装备、旅客服务等铁路行业各领域的先进产品及技术。展会现场智能京张&#xff1a;将首次实现时速350公里自动驾驶…

CentOS下安装MySQL报安装文件conflicts错误:

2019独角兽企业重金招聘Python工程师标准>>> 第一&#xff1a;报这个错误&#xff0c;说明已经安装或相关文件已经存在&#xff0c;把已经存在的文件卸载了就可以了&#xff1a; rpm -e --nodeps mysql-libs-5.1.* 转载于:https://my.oschina.net/u/3197158/blog/1…

inc指令是什么意思_西门子PLC一些指令

指令(英文全称意思)∶指令含义1、LD ( Load装载):动合触点2、LDN (Load Not不装载):动断触点3、A(And与动合):用于动合触点串联4、AN (And Not与动断):用于动断触点串联5、o(Or 或动合):用于动合触点并联6、ON(Or Not 或动断):用于动断触点并联7、(Out输出):用于线圈输出8、OLD…

touchesEnded不响应

为什么80%的码农都做不了架构师&#xff1f;>>> http://blog.csdn.net/assholeu/article/details/16363241 touchesEnded不响应主要存在以下几种情况 case 1 : userInteractionEnabled 部分控件如UIImageView&#xff0c;userInteractionEnabled默认为NO&#xff0…

iOS开发人员不容错过的10大工具

内容简介 1、iOS简介 2、iOS开发十大实用工具之开发环境 3、iOS开发十大实用工具之图标设计 4、iOS开发十大实用工具之原型设计 5、iOS开发十大实用工具之演示工具 6、iOS开发十大实用工具之视频制作 7、iOS开发十大实用工具之分析工具 iOS简介 说起iOS&#xff0c;自然不必多介…

算法学习系列(十):用数组模拟链表、双链表、栈、队列、单调栈、单调队列

目录 引言一、数组模拟链表1.模板2.例题3.测试 二、数组模拟双链表1.模板2.例题3.测试 三、数组模拟栈1.模板2.例题3.测试 四、数组模拟队列1.模板2.例题3.测试 五、数组模拟单调栈1.例题模板2.测试 六、数组模拟单调队列1.例题模板2.测试 引言 首先说一下为什么要拿数组来模拟…

为什么你的路由器穿墙能力差?看完秒懂

1、信号弱赖我咯? 不管你承认与否&#xff0c;只要有墙家中就会存有信号死角&#xff0c;不要小看一墙之隔。如何让路由器的信号增强? 网上一搜旁门左道真不少&#xff0c;什么调整天线寻找合理角度&#xff0c;又或是用易拉罐DIY一个信号放大器&#xff0c;然鹅并非简单的将…

fish工具_Python程序员使用哪些开发工具

Python程序员使用哪些开发工具?很多Python学习者想必都会有如下感悟&#xff1a;最开始学习Python的时候&#xff0c;因为没有去探索好用的工具&#xff0c;吃了很多苦头。后来工作中深刻体会到&#xff0c;合理使用开发的工具的便利和高效。今天&#xff0c;北京学佳澳小编总…

[shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证

本文地址&#xff1a;http://blog.csdn.net/sushengmiyan/article/details/39933993shiro官网: http://shiro.apache.org/shiro中文手冊&#xff1a;http://wenku.baidu.com/link?urlZnnwOHFP20LTyX5ILKpd_P94hICe9Ga154KLj_3cCDXpJWhw5Evxt7sfr0B5QSZYXOKqG_FtHeD-RwQvI5ozyT…

Web安全之Cookie劫持

1.Cookie是什么? 2.窃取的原理是什么? 3.系统如何防Cookie劫持呢? 看完这三个回答&#xff0c;你就明白哪位传奇大侠是如何成功的!!! Cookie: HTTP天然是无状态的协议&#xff0c;为了维持和跟踪用户的状态&#xff0c;引入了Cookie和Session。Cookie包含了浏览器客户端的用…

运动估计简介

运动估计( Motion Estimation) 维基百科链接&#xff1a;http://en.wikipedia.org/wiki/Motion_estimation运动估计的应用有很多&#xff0c;最初的应用的领域是视频的编码。运动估计算法一般分为: 像素递归法pel-recursive algorithm (PRA)和块匹配法 block-matching algorith…