在最开始学习js的时候,我看书上写着,创建一个数组,一个对象通常使用new,如下:

 var  arr=new Array(),//arr=[]
obj=new Object();//obj={}

  到了后来,我们开始进行面向对象的学习的时候就开始遇到下面的代码:

 function Qwe(id) {
this.id = id;
}
Qwe.prototype.name = 'qwe';
Qwe.prototype.age=18;
var asd = new Qwe(2);

  有一点基础的同学就可以得知我们按照Qwe的样子制作了一个asd,并且给了他一个独一无二的id2。在这简单的几个代码中,我们就完成了对一个数组或者对象的创建,而new究竟在其中做了点啥呢?

  根据英语的字面意思翻译,new的意思是新的,也就是说创建arr,并且给arr赋值为新的数组(obj同理)。其实不然,我们在new的过程中只是模仿一个模子(Array也好,Object也罢)新建了一个对象,并且继承了我们所使用的模子的一些方法和内容。

 function Qwe(id) {
this.id = id;
}
Qwe.prototype.name = 'qwe';
Qwe.prototype.age=18;
var asd = new Qwe(2); asd.id//
asd.name//'qwe'
asd.age//18

  就拿上面的asd来说,它的id是构造函数Qwe设置的,除此之外所有的属性和方法都是继承自Qwe的原型对象——prototype属性。

  如果你上面的没看懂,那我就用通俗的语言来讲解一下。

  高中的时候其实很学渣,渣到上课天天玩手机(至于后来奋发图强混进一本院校是后话),当时玩了一款qq家园里面叫《江湖ol》的游戏。当时我玩的那个区是五区,仗着网速好手机好在那个区也算是排行榜前几的玩家。当时情人节搞活动,抽奖送坐骑情情兔,现在看来只不过是一堆可能有规律的乱码而已。因为时间过去很久了,我也无法完全想起所有,大概就是:

  

情情兔
编号:00001
速度:50
防御:37
敏捷:21
攻击力:37
生命值:500

  因为我获得的是当时的全区第一个情情兔,所以我的编号是00001。用现在的眼光来看,无非是以下的样子:

情情兔 = {
编号: 00001,
速度速度: 50,
防御: 37,
敏捷: 21,
攻击力: 37,
生命值: 500,
}

  当我后来研究我和我朋友的装备的时候,我发现我的天字一号马和朋友的天字n号马的属性居然只有编号的差别!!!那么,无良的同行在制作这个坐骑的时候大概就是改一下编号吧:

 var 情情兔数组=[];//安置情情兔坐骑
for(var i=0;i<1000;i++){
  var 情情兔 ;
情情兔 = {
编号: i,//差别在此
速度速度: 50,
防御: 37,
敏捷: 21,
攻击力: 37,
生命值: 500,
}
情情兔数组.push(情情兔);
}
加载生产(情情兔数组);//制作了大批量的有编号的情情

  但是问题是,在这个伪代码中,我们要重复创建1000次的情情兔,然后给它赋值的对象值的属性仅仅有一个是不同的,这样就造成了一定意义上的浪费。作为一个勤(lan)奋(duo)的程序员,这种问题我们应为这样去做:

 var 情情兔数组=[];//安置情情兔坐骑
for(var i=0;i<1000;i++){
  var 情情兔 ;
情情兔=new 情情兔模板(i);
情情兔数组.push(情情兔);
}
加载生产(情情兔数组);//制作了大批量的有编号的情情

  因此,我们可以先创造一个坐骑原型——情情兔模板,在这个里面的prototype呢我们放置所有相同数值的属性为新创建的对象提供可以继承属性的路径或者说目标。我们用new来实现一下:

function 情情兔模板(id){
this.id=id
}
情情兔模板.prototype.速度=50
情情兔模板.prototype.防御=37

情情兔模板.prototype敏捷=21
情情兔模板.prototype攻击力=37
情情兔模板.prototype生命值=500
var 情情兔1=new 情情兔模板(1)
//情情兔1={编号:1,速度速度:50,防御:37,敏捷:21,攻击力:37,生命值:500}

  OK,一个简单的情情兔模板就诞生了。

  但是到了这里,有的同学就要问了,既然是下面都是属性,那么为什么不直接就写一个LoveRabbit.prototype={速度速度=50,防御=37,敏捷=21,攻击力=37,生命值=500}呢?其实当我们打印很多对象或者别的东西的prototype时候,会发现有一个叫做constructor的属性,字面翻译的意思就是构造函数,这个属性的值呢就是new后面的字样,也就是说,其实我们看到的种种都是一个构造函数,毕竟在js的世界中,后缀是()的大部分都是一个运行的函数。

  那么我们就可以猜测了:在这个函数中,一开始呢我们肯定会创建一个新的对象,对象没有prototype属性,只有函数有prototype属性。每个对象的__proto__属性指向自身构造函数的prototype,也就是我们把新制造的对象的__proto__赋值为构造函数的prototype。当然呢,我们会给这个对象新加别的属性。

  因此,在上一步的情情兔模板的new的函数中,其实应该是这样的:

function 情情兔模板(id){
var 新情情兔 = {}
新情情兔 .__proto__ = 情情兔模板.prototy'pe
新情情兔 .id= id
return 新情情兔
}
情情兔模板.prototype = {
  constructor:情情兔模板,//非常重要的一条,因为我们要知道构造函数,也就是来源。
  速度速度:50,
  防御:37,
  敏捷:21,
  攻击力:37,
  生命值:500
}

  在上面我们可以看出区别,new在这个构造函数中做了啥呢:

    1.首先,先创建了一个新的对象。

    2.然后呢,把构造函数的公共的属性复制了一份给这个新对象,这也就是prototype——原型。

    4.接着把私有属性赋赋值,毕竟创建就要造个独一无二的。

    3.返回这个新的对象。

  在es6中,我们引入了class类这个概念,上面的代码我们可以写为:

     class 情情兔模型 {
constructor(id) {
this.编号 = id;
this.速度=50;
this.防御=37;
this.敏捷=21;
this.攻击力=37;
this.生命值=500;
}
}
var 情情兔=new 情情兔模型(1)

  其实,class也是一个语法糖,里面有一个构造函数constructor,原理上是和es5的类似的。

  终于,我们就可以愉快地通过new来大批量的创建各种新的对象了。

  由此观之,new就是一个语法糖,为了更好地节省代码,来体现程序员的聪(lan)明(duo)。

  

  如果您觉得我的博文有用,请不要吝啬您的关注。如需转载,请标明出处,谢谢。

js到底new了点啥的更多相关文章

  1. 【转】Node.js到底是用来做什么的

    Node.js的到底是用来做什么的 在阐述之前我想放一个链接,这是国外的一个大神,对于node.js非常好的一篇介绍的文章,英文比较好的朋友可以直接去阅读,本文也很大程度上参考了这篇文章,也同时感谢知 ...

  2. Angular、React.js 和Node.js到底选谁?

    为了工作,程序员选择正确的框架和库来构建应用程序是至关重要的,这也就是为什么Angular和React之间有着太多的争议.Node.js的出现,让这场战争变得更加复杂,虽然有选择权通常是一件很棒的事情 ...

  3. Node.js到底是什么

    接触前端也有一段时间了,逐渐开始接触Node.js,刚刚接触Node.js的时候一直都以为Node.js就是JavaScript,当对Node.js有一定的了解之后,其实并不然两者之间有关系,其中的关 ...

  4. Node.js到底是做什么的?这是我看到最好的解释了

    作者:贾厂长链接:https://www.zhihu.com/question/33578075/answer/56951771来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  5. 「标准」的 JS风格

    首先,这份 JS风格指南已经在我司的前端团队实行半年多了: 其次,在程序员的世界里,从入行到资深都需要面对几个世界级的难题,如: 世界上最好的编辑器是什么? 是用空格还是 TAB?用空格还特么衍生出 ...

  6. Vue.js先入个门看看

    使用vue.js原文介绍:Vue.js是一个构建数据驱动的web界面库.Vue.js的目标是通过尽可能简单的API实现响应式数据绑定和组合的视图组件.vue.js上手非常简单,先看看几个例子: 例一: ...

  7. 让我欲罢不能的node.js

    从我大一接触第一门编程语言C开始,到现在工作三年陆续接触到了C.汇编.C++.C#.Java.JavaScript.PHP,还有一些HTML.CSS神马的,从来没有一门语言让我像对node.js一样的 ...

  8. NODE.JS学习的常见误区及四大名著

    NODE.JS学习的常见误区及四大名著 前段时间由于不满于社区里很多人对于NODE.JS的种种误解而写了一篇文章名为: NODE.JS之我见:http://www.cnblogs.com/pugang ...

  9. js的动态加载、缓存、更新以及复用(二)

    上一篇发出来后得到了很多回复,在此首先感谢大家的热情捧场!有的推荐第三方框架,比如 In.js.requrieJS.sea.js.lab.js等.这个开阔了眼界,以前只知道sea.js,省去了自己搜索 ...

随机推荐

  1. 利用xcode生成的app生成可以在iphone和itouch上运行的ipa安装包

    在编译好的真机版目录下的.app文件,至于生成真机可以运行的app的方法,有两种方式,一种是交99美元获得一个证书,另外一种是破解的方式,在此不再详述,本文假设你已经生成了真机上可以运行的app包了( ...

  2. intern

    java.lang.String的intern()方法"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方 法没什么用处.但实际 ...

  3. Java数据持久层框架 MyBatis之API学习四(xml配置文件详解)

    摘录网址: http://blog.csdn.net/u010107350/article/details/51292500 对于MyBatis的学习而言,最好去MyBatis的官方文档:http:/ ...

  4. SpringMvc4.x--@ControllerAdvice注解

    通过@ControllerAdvice.我们可以将对于控制器的全局配置放置在同一个位置,注解了@ControllerAdvice的类的方法可以使用@ExceptionHandler,@InitBind ...

  5. Spring切面优先级

    项目中有两个切面,这两个切面都作用于同一个方法,哪个先执行哪个后执行呢,所以要定义一个切面的优先级 import java.util.Arrays; import org.aspectj.lang.J ...

  6. Arduino库函数中文说明

    #define 常量名 常量值 % 取模运算符 String abc  /  char abc[n]  定义字符串 pinMode(pin,mode);  用于引脚的初始化  mode包括 INPUT ...

  7. [Git] git log命令

    这是git的新系列,不常用的命令和其参数比较容易记不住,干脆将常用的记录下来,日后查查方便也是好的,一篇文章一个git命令,长短根据命令有所不同. git log命令主要用于查看提交历史,同时根据添加 ...

  8. BSA Network Shell系列-redi命令

    redi ## 1 功能概述 redi将输出重定向到一个文件中 ## 2 语法 redi [-?] [-a] filename ## 3 使用示例 1 将输出重定向到隐式路径所在主机的/tmp/hah ...

  9. 了解ViewFlipper工作机制

    平时我们在使用ViewFlipper的时候一方面感叹ViewFlipper的使用很简单,另一方面,我们时常感叹ViewFlipper给我们的接口方法太少,很多常用的效果都不好做,很难施展拳脚,这篇文章 ...

  10. Struts2 (二)

    1 自定义结果视图 1.1 自定义一个类实现com.opensymphony.xwork2.Result接口. package com.xuweiwei.action; import com.open ...