JS基础如何理解对象
这几天跟几个同事聊天发现他们对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工具类或公用方法时,应该注释告诉你的调用者怎么去使用你提供的公用内容,或者提供工厂方法。
最新文章
- Java 多线程之单例设计模式
- 远程连接Oracle时出现ORA-01034 和ORA-27101 的解决办法
- VM12.1.1 下载 序列号
- 如何理解JS回调函数
- Zookeeper集群的安装和使用
- HDU 4431 Mahjong(模拟题)
- Apache代理Tomcat实现session共享构建网上商城系统
- AX 与Citrix打印机问题
- iOS原生地图开发进阶——使用导航和附近兴趣点检索
- 【HDOJ】3068 最长回文
- 如何优雅的输出PHP调试信息
- MySql 在cmd下的学习笔记 —— 有关储存过程的操作(procedure)
- 利用cookie实现iframe刷新时停留在当前页面
- MVC 获取控制器名称和Action名称(转载)
- 安装jdk的时候为什么会有两个jre文件
- Kotlin 型变 + 星号投影(扯蛋)
- 学JS的心路历程 - JS的Class
- Linux查看磁盘读写
- Java_正则表达式&;时间日期
- 【整理总结】代码沉淀 - Caliburn.Micro - MV*模式短小精悍的框架
热门文章
- iOS开发面试题整理 (一)
- html 基础之 <;link>;标签
- Java并发编程之闭锁简介
- 在world中批量调整图片的大小
- Dubbo使用详解及环境搭建
- 【搜索引擎Jediael开发笔记】v0.1完整代码
- javascript 操作元素属性的方法
- php.ini 全站,和htaccess web目录 默认头部和尾部 auto_prepend_file
- php 函数之 )_each()list()implode()explode()in_array()
- ~/microwindows-0.89pre8/src/bin$ ./nano-X error:Cannot bind to named socket