大部分讲 new 的文章会从面向对象的思路讲起,但是我始终认为,在解释一个事物的时候,不应该引入另一个更复杂的事物。

今天我从「省代码」的角度来讲 new。

---------------------------

想象我们在制作一个策略类战争游戏,玩家可以操作一堆士兵攻击敌方。

我们着重来研究一下这个游戏里面的「制造士兵」环节。

一个士兵的在计算机里就是一堆属性,如下图:

我们只需要这样就可以制造一个士兵:

var 士兵 = {ID: 1, // 用于区分每个士兵 兵种:"美国大兵", 攻击力:5, 生命值:42, 行走:function(){ /*走俩步的代码*/}, 奔跑:function(){ /*狂奔的代码*/ }, 死亡:function(){ /*Go die*/ }, 攻击:function(){ /*糊他熊脸*/ }, 防御:function(){ /*护脸*/ } } 兵营.制造(士兵) 

制造一百个士兵

如果需要制造 100 个士兵怎么办呢?

循环 100 次吧:

var 士兵们 = []
var 士兵
for(var i=0; i<100; i++){士兵 = {ID: i, // ID 不能重复兵种:"美国大兵",攻击力:5,生命值:42, 行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }}士兵们.push(士兵)
}兵营.批量制造(士兵们)

哎呀好简单。

质疑

上面的代码存在一个问题:浪费了很多内存。

  1. 行走、奔跑、死亡、攻击、防御这五个动作对于每个士兵其实是一样的,只需要各自引用同一个函数就可以了,没必要重复创建 100 个行走、100个奔跑……
  2. 这些士兵的兵种和攻击力都是一样的,没必要创建 100 次。
  3. 只有 ID 和生命值需要创建 100 次,因为每个士兵有自己的 ID 和生命值。

改进

看过我们的专栏以前文章(JS 原型链)的同学肯定知道,用原型链可以解决重复创建的问题:我们先创建一个「士兵原型」,然后让「士兵」的 __proto__ 指向「士兵原型」

var 士兵原型 = {兵种:"美国大兵",攻击力:5,行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}
var 士兵们 = []
var 士兵
for(var i=0; i<100; i++){士兵 = {ID: i, // ID 不能重复生命值:42}/*实际工作中不要这样写,因为 __proto__ 不是标准属性*/士兵.__proto__ = 士兵原型 士兵们.push(士兵)
}兵营.批量制造(士兵们)

优雅?

有人指出创建一个士兵的代码分散在两个地方很不优雅,于是我们用一个函数把这两部分联系起来:

function 士兵(ID){var 临时对象 = {}临时对象.__proto__ = 士兵.原型临时对象.ID = ID临时对象.生命值 = 42return 临时对象
}士兵.原型 = {兵种:"美国大兵",攻击力:5,行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}// 保存为文件:士兵.js

然后就可以愉快地引用「士兵」来创建士兵了:

var 士兵们 = []
for(var i=0; i<100; i++){士兵们.push(士兵(i))
}兵营.批量制造(士兵们)

JS 之父的关怀

JS 之父创建了 new 关键字,可以让我们少写几行代码:

只要你在士兵前面使用 new 关键字,那么可以少做四件事情:

  1. 不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);
  2. 不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);
  3. 不用 return 临时对象,因为 new 会帮你做;
  4. 不要给原型想名字了,因为 new 指定名字为 prototype。

这一次我们用 new 来写

function 士兵(ID){this.ID = IDthis.生命值 = 42
}士兵.prototype = {兵种:"美国大兵",攻击力:5,行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}// 保存为文件:士兵.js

然后是创建士兵(加了一个 new 关键字):

var 士兵们 = []
for(var i=0; i<100; i++){士兵们.push(new 士兵(i))
}兵营.批量制造(士兵们)

new 的作用,就是省那么几行代码。(也就是所谓的语法糖)

注意 constructor 属性

new 操作为了记录「临时对象是由哪个函数创建的」,所以预先给「士兵.prototype」加了一个 constructor 属性:

士兵.prototype = {constructor: 士兵
}

如果你重新对「士兵.prototype」赋值,那么这个 constructor 属性就没了,所以你应该这么写:

士兵.prototype.兵种 = "美国大兵"
士兵.prototype.攻击力 = 5
士兵.prototype.行走 = function(){ /*走俩步的代码*/}
士兵.prototype.奔跑 = function(){ /*狂奔的代码*/  }
士兵.prototype.死亡 = function(){ /*Go die*/    }
士兵.prototype.攻击 = function(){ /*糊他熊脸*/   }
士兵.prototype.防御 = function(){ /*护脸*/       }

或者你也可以自己给 constructor 重新赋值:

士兵.prototype = {constructor: 士兵,兵种:"美国大兵",攻击力:5,行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}

完。

喜欢本文,请关注我的专栏《前端开发指南》。

想学前端?到 Q 群里找我:108801207

转载于:https://www.cnblogs.com/Frank99/p/9049365.html

转自知乎大神----JS 的 new 到底是干什么的?相关推荐

  1. 罗素问题 ——来自知乎大神

    作者:LLLBK 链接:https://www.zhihu.com/question/20511488/answer/133390930 来源:知乎 著作权归作者所有,转载请联系作者获得授权. 知乎相 ...

  2. 教你如何专业地故弄玄虚,成为一代大神

    作为在网赚圈浪荡快十年的人,按理脸皮应该够厚了,但是每天面对陌生粉丝来找我,左一句老师,右一句大神,着实很不习惯,听着有点脸红,也有点刺耳. 人要有自知之明,尽管在互联网上混的时间还算长,但是这些年操 ...

  3. JS高级群的日常!写一个从10到0的倒计时,用console.log打印,不可以用 setInterval!本来说好的研究avalonJS最后演变成了看着大神在那边互相比拼实力。。...

    JS高级群的日常!写一个从10到0的倒计时,用console.log打印,不可以用 setInterval!本来说好的研究avalonJS最后演变成了看着大神在那边互相比拼实力.. 小森 执行一个函数 ...

  4. 这是一段有毒的js代码,求大神解释!!!

    这是一段有毒的js代码,感兴趣的同学可以试一试,求大神解释!!! function lock() {while (true); } function nullFunction() {}alert(nu ...

  5. python爬虫:关于解决request.get和点击查看网页源代码的内容不同的问题//及大神版js加密参数获取教程指路

    首先声明:爬虫小白,虽然爬过几个网站,但是知识几乎都是实践中获取,如果以下说的不对的,请多指正,谢谢!谨此给和我一样的小白提供一个解题思路! 目录 问题背景 菜鸡版解决方案 大神版js加密参数获取教程 ...

  6. HTML/CSS/Js/Jquery/PHP网站0基础开发到大神系列【飞鸽学院】

    课程介绍 简 介 html,css,javascript,jquery,php+mysql,网站0基础开发涵盖前端到后端成就你的大神之路 学习目标 php高级开发工程师,具有一定的项目经验,能进入企业 ...

  7. 删库跑路大神「后悔」了?我只不过犯了大家都会犯的编程错误!

      视学算法报道   编辑:好困 袁榭 [新智元导读]在开源程序界惹出「删库跑路」大新闻的开发者Marak Squires,最近发声:「人无完人,编程错误而已,GitHub你就不用再封我号了嘛!」 2 ...

  8. python大神教程_大神python教程415集全套,拿走不谢

    大神的教程 由北京尚学堂高淇老师亲自录制,2019Python自学教程全新升级为<Python+数据分析+机器学习>能力逐级提升,打造技能更全面的全栈工程师. Python作为一种编程语言 ...

  9. 人物丨深度学习大神Hinton推翻自己30年的学术成果另造新世界

    作者:胡永波 Hinton,这个以"深度学习之父"和"神经网络先驱"响彻AI领域的名字,他的一举一动,都是热点导向. 当我们远望一位顶级人物时,除了他的学术,也 ...

最新文章

  1. bash . dot using
  2. CentOS文件浏览器设置
  3. python中index从列表中查_在Python中查找包含它的列表的项目的索引
  4. 月亮之上--数学分析版
  5. 设计模式(三)--适配器模式
  6. audino python_用 Python 实现 PowerDesigner 数据模型文件的处理
  7. spring 使用其他类protected方法_Java操作bean、属性、方法的使用工具类
  8. MySQ随笔2(连接表、分组)
  9. mysql开源内库_king
  10. VB.NET 教程_02_常见对象
  11. 简单的流媒体服务器(EasyDarwin的安装搭建)
  12. 建模方法(四)-因子分析定义和应用
  13. FOC——14.15.过流保护电路与单片机外围电路
  14. _stdcall相关
  15. mac虚拟机改显存_虚拟机mac怎么增大显存
  16. 从零实战:爬2019富豪榜进行数据分析
  17. js 根据链接生成二维码
  18. TCP/IP协议第一章笔记
  19. html网页设计文字出现动画,网页设计中的文字与图片的动画有以下几种形式
  20. 数据结构考研大纲浅析

热门文章

  1. 【收藏】wsl2 出现 Vmmem内存占用过大问题解决
  2. jenkins清除、修改admin主账号的密码
  3. JVM调优:CMS的执行过程及存在的问题
  4. eureka之EurekaInstanceConfig接口的作用
  5. Linux clear指令
  6. nginx 配置文件nginx.conf结构
  7. 请讲一下浏览器从接收到一个URL,到最后展示出页面,经历了哪些过程
  8. MySQL使用精确匹配和范围查询的效率差别
  9. RabbitMQ 消息确认机制confirm代码编写
  10. 小程序分享朋友圈_改造小程序,增加分享朋友圈代码