这几天跟几个同事聊天发现他们对javascript什么时候该用new都不是很了解。

1、javascript的function什么时候该new什么时候不该new?
我觉得主要的问题还是集中在javascript的弱类型上面。

new在干什么

首先我们知道new是干什么,以我们java或.net的语言经验显然在创造对象。是的,不管是java还是.net。他是在创建一个对象。

new后面是什么

那么我们考虑一下new的后面是什么,(java和.net)一般是被一个class修饰的类名称。那么我们考虑一下,我们实例一个对象是干什么或者说设计者的目的是什么,那么一般情况下对象都会包含这些成员,属性与行为或者其中之一(我们在javaEE中DAO只有行为,POJO只有属性),有没有看到过既没有属性也没有行为的对象(当然类可以这么设计,但是没有意义)。

javascript的new干了什么
那么javascript的new干了什么?new其实开辟了内存空间创建了一个object这个object就是this,然后这个this的prototype指向了函数本身的prototype。
也就是说去new一个function的时候,开辟了一个this,这个this就是对象本身,再想想你去实例一个对象。你要拿到对象的成员,属性或方法或其中之一。this本身有几种方式能声明成员,一种在function函数体内部用this.的方式声明,例如:this.a = '123',其实就是给他的a属性赋了一个‘123’字符串,当然也可以赋值行为。还有种方式就是通过原型继承,通过function函数的.prototype的方式。
好了,因为javascript是弱类型,他没有class修饰,没有是否有返回值修饰,只有一个function修饰。所以function是否是构造函数很难通过函数头知道。所以是否需要去new就需要你去揣摩function的目的,他到底是不是构造函数。

实例代码说明
既然他是弱类型,他们可以根据内部的条件选择到底是做构造函数用,还是做普通函数用。再加上我们很多程序员都是其他语言出身,很少有人系统的学习了javascript,所以就很混淆。
下面我们来看混淆的例子吧。

Js代码

  • function Hello() {
  • this.a = '123';
  • this.b = function () {
  • alert('b');
  • }
  • return this;
  • }
  • Hello.prototype.c = function() {
  • alert('c');
  • }
  • var aHello = new Hello();
  • var bHello = Hello();
  • alert(aHello.a)
  • alert(bHello.a)
  • aHello.b();
  • bHello.b();
  • aHello.c();
  • bHello.c();

你会发现bHello.c()是执行不了的。在看看上面的函数,他为什么既能new又能不new。
new其实开辟了内存空间创建了一个object这个object就是this,然后这个this的prototype指向了函数本身的prototype。
不new就是执行了这个函数,最后return this就是返回了这个执行函数的宿主,其实就是window本身。
所以c函数是绑定在Hello的prototype上的,所以window上根本没有。

但是就出现了一个问题,就是如果在不执行c方法或者c本身不是通过原型继承的方式的话(就是不通过Hello的prototype方式,通过直接给this赋值的方式),其实创建的this的内容和window增加的内容是一样的,程序员会本能的以为new和不new是一样的。这样就掉坑里去了。

总结:javascript弱类型语言,一个函数即使是普通的执行函数,你new或不new都会出现编译器异常。
new与不new我们要做好以下几点。
1、首先大家要了解new本身干了什么,然后看函数创建者的意图,看函数结构。
2、一个好的程序员在提供某个javascript工具类或公用方法时,应该注释告诉你的调用者怎么去使用你提供的公用内容,或者提供工厂方法。

最新文章

  1. Java 多线程之单例设计模式
  2. 远程连接Oracle时出现ORA-01034 和ORA-27101 的解决办法
  3. VM12.1.1 下载 序列号
  4. 如何理解JS回调函数
  5. Zookeeper集群的安装和使用
  6. HDU 4431 Mahjong(模拟题)
  7. Apache代理Tomcat实现session共享构建网上商城系统
  8. AX 与Citrix打印机问题
  9. iOS原生地图开发进阶——使用导航和附近兴趣点检索
  10. 【HDOJ】3068 最长回文
  11. 如何优雅的输出PHP调试信息
  12. MySql 在cmd下的学习笔记 —— 有关储存过程的操作(procedure)
  13. 利用cookie实现iframe刷新时停留在当前页面
  14. MVC 获取控制器名称和Action名称(转载)
  15. 安装jdk的时候为什么会有两个jre文件
  16. Kotlin 型变 + 星号投影(扯蛋)
  17. 学JS的心路历程 - JS的Class
  18. Linux查看磁盘读写
  19. Java_正则表达式&时间日期
  20. 【整理总结】代码沉淀 - Caliburn.Micro - MV*模式短小精悍的框架

热门文章

  1. iOS开发面试题整理 (一)
  2. html 基础之 <link>标签
  3. Java并发编程之闭锁简介
  4. 在world中批量调整图片的大小
  5. Dubbo使用详解及环境搭建
  6. 【搜索引擎Jediael开发笔记】v0.1完整代码
  7. javascript 操作元素属性的方法
  8. php.ini 全站,和htaccess web目录 默认头部和尾部 auto_prepend_file
  9. php 函数之 )_each()list()implode()explode()in_array()
  10. ~/microwindows-0.89pre8/src/bin$ ./nano-X error:Cannot bind to named socket