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属性!所以不会影响

浅谈面向对象的javascript几个特性相关推荐

  1. html5交互效果,浅谈HTML5 CSS3的新交互特性

    本文标题的这副图片,是用Phosotshop制作的.但是,在搜索引擎中你却无法搜索到它,搜索引擎还没有强大到能够识别图片里面的文字.并且由于图片的体积不算太小,可能网速慢的网友在浏览的时候不得不耐心的 ...

  2. html5中的css特性,浅谈HTML5 CSS3的新交互特性

    本文标题的这副图片,是用phosotshop制作的.但是,在搜索引擎中你却无法搜索到它,搜索引擎还没有强大到能够识别图片里面的文字.并且由于图片的体积不算太小,可能网速慢的网友在浏览的时候不得不耐心的 ...

  3. 【c++开篇】浅谈面向对象与面向过程(举例说明)

    浅谈面向对象与面向过程 前言:刚接触C++第一时间,都会经常听到这样一话:C语言面向过程,C++面向对象.在老师模拟面试时,问道你对面向对象与面向过程的认识时,我有点懵答的不是很完整,刚好C++开篇写 ...

  4. 『软件工程13』浅谈面向对象方法,统一建模语言UML

    浅谈面向对象方法UML 一.UML的含义 二.UML的主要内容 1.UML的概念模型 2.UML概念模型图例 三.UML的基本构造块 1.UML中的事物 (1)UML中的四种事物 (2)UML中各种事 ...

  5. 【转】浅谈面向对象的坏处

    转自:https://blog.csdn.net/fishmai/article/details/52079766 1.性能. 现时C++可以说是支持OOP范式中最为常用及高性能的语言.虽然如此,在C ...

  6. 【JavaScript】——浅谈js(JavaScript)

    [前言] 学习javascript的知识,原来在浏览网页时炫酷的动态效果就是js在幕后操作,js在Web开发中扮演着重要的角色,被广泛应用到各个领域:地图搜索,,用户注册.验证,网上购物.Web聊天- ...

  7. 浅谈面向对象的编程思想:如何优雅地把大象装进冰箱?

      许多人刚学编程时,想必都听到过这样的话:"*语言是面向对象的,而***语言是面向过程的".那时的新人还懵懵懂懂,就被大牛或者书上的大牛骗去学了一种听起来很厉害的语言,然而学了半 ...

  8. 浅谈面向对象与女娲造人

    由于课程需要,学习Java和面向对象也已经好几个月了,今天来浅浅的谈论一下我对面向对象的理解. 什么是面向对象? 如果你百科或者wiki一下,倒是能翻出一大堆来.如果你嫌这些答案不够深沉,不够装逼,甚 ...

  9. 浅谈面向对象程序设计方法

    目录 定义 基本思想 早期发展 背景 审视问题域的视角 抽象级别 封装体 可重用性 特征 对象唯一性 抽象性 继承性 多态性(多形性) 开发方法 Booch方法 Coad方法 OMT方法 UML(Un ...

最新文章

  1. php定义变量f= e怎么写,php变量怎么定义-PHP问题
  2. nginx 集群部署_如何备份和还原您的Kubernetes集群资源和持久卷?
  3. 普林斯顿大学计算机科学与技术专业硕士项目拒信
  4. 移动app部分机型无法唤起h5支付宝支付_用这段代码对App说:喂,醒醒!App,到你出场了!...
  5. 解决redis-cli连接时出现Could not connect to Redis at 127.0.0.1:6379: Connection refused
  6. php imagick手册,PHP中使用Imagick实现各种图片效果实例
  7. Java Swing Mysql学生选课系统
  8. 麦肯锡指出布局金融生态圈对中国国内银行意义重大
  9. 一个有很多QT免费应用例程的网站
  10. redis和couchbase的比较
  11. Atitit 防烫伤指南与规范 attilax总结
  12. MODIS数据下载流程之地理空间数据云
  13. 电脑自动开机+自动输入密码
  14. android浏览器有桌面模式么,手机浏览器添加到主屏幕(桌面)的图标设置以及WebApp模式...
  15. hexo next主题去掉码市的Coding Pages等待页
  16. Keras实例教程(1)
  17. 阿里云香港节点全面故障给我们的启示
  18. 中国中试工厂市场现状研究分析与发展前景预测报告
  19. 区块链智能资产的“硬链接”思考
  20. 纽约时报称刘强东卷入悉尼嫩模性侵案 京东回应:深表同情

热门文章

  1. 阿里云 centos mysql_在阿里云的CentOS环境中安装配置MySQL的教程
  2. 《关于我的那些面经》滴滴Java岗(附答案)
  3. C++:17---sizeof运算符
  4. (十)nodejs循序渐进-高性能游戏服务器框架pomelo之介绍和安装篇
  5. mysql数据库老是被锁怎么解决_Mysql数据库全局锁是如何引起的,如何解决?
  6. codeforces 617A-C语言解题报告
  7. 解决:springcloud eureka 注册的服务config-client 状态Status:UNKNOWN (1)
  8. 解决 VS Code 保存时候自动格式化
  9. Hadoop之Flume详解
  10. Centos7 下yum安装mysql