在这端代码执行的末尾,你会不会hi变量回事函数中的hi了?你会不会认为这不是按引用传递了? 对值传递和引用传递产生质疑了?
  
  1 var hi = {};
  
  2 function sayHello(hi) {
  
  // 这样来给hi赋值,声明的hi变量不会有任何变化,在函数外侧hi还是那个{}
  
  hi = {
  
  a: 'b'
  
  };
  
  console.log(yongshiyule178.com'in function hi : ' + hi.a);
  
  alert(hi.a);
  
  }
  
  sayHello(hi);
  
  console.log(www.mcyllpt.com 'out function: ' + hi.a); // 此时函数外的hi还是{}
  
  辨析:
  
  1 是实参hi
  
  2 是形参hi
  
  虽然名字同名但同名不是同一个变量,是两个不同的变量,虽然同名同名,但存放的内存位置不同。
  
  同名会迷惑你。
  
  实参hi是一个对象,在sayHello被调用时,会将引用赋值给形参hi,在函数内部我们将一个新对象赋值给形参hi,这时形参hi的引用发生了变化,指向了新的对象,但实参hi的引用并没有发生变化,所以函数调用后实参hi还是那个实参hi,这个函数值传递形式还是按引用传递,只不过我们在函数内部改变了形参hi的引用指向。如果不改变引用指向,可以在函数中修改实参hi的属性值。
  
  不要被表象所迷惑。
  
  这个问题是我在阅读seajs的源码发现的困惑,为什么这样写,在另一个模块中require是不能获取到暴露出的对象:
  
  seajsUtil.js
  
  define(function (require, exports, module) {
  
  exports = {
  
  a: 'meng',
  
  b: 'miao'
  
  };
  
  });
  
  seajsDemo.js
  
  define(function (require, exports, module) {
  
  var seaUtil = require(www.michenggw.com./seaUtil');
  
  console.log(seaUtil.a); // 报a未定义
  
  });
  
  理解了以上的困惑,就告诉我们正确的暴露对象的方法是:
  
  // 这样才是使用exports暴露变量和属性的正确姿势,exports本身是一个空对象{},要在空对象上进行添加属性和函数
  
  define(function (require, exports, module) {
  
  exports.a = 'meng';
  
  exports.b = 'miao';
  
  exports.sayHello = function(){
  
  alert('hi');
  
  }
  
  });
  
  // 直接return对象或者属性,这样就回避了exports属性暴露,使用return直接暴露,使用return可以暴露各种类型的值。
  
  // 是的适合,使用起来感觉比exports更便捷。暴露模块内容的方法可以是情况进行选择。
  
  define(function (require, exports, module) {
  
  return {a: 'meng', b: 'miao'};
  
  });
  
  //这是seajs的暴露模块属性的代码:
  
  /**
  
  * 如果构造函数factory不返回,则exports取mod.exports变量作为返回对象。也即是seajs模块的的交互,句柄持有的对
  
  * 象,要么是factory的return对象,要么是exports对外发布的对象。
  
  * factory被赋予的exports是一个对象,所以通过exports暴露的就是一个对象。
  
  */
  
  var exports = isFunction(factory) ?
  
  factory(require, mod.exports = {}, mod) :
  
  factory
  
  if (exports === undefined) {
  
  exports = mod.exports
  
  }
  
  // Reduce memory leak
  
  delete mod.factory
  
  mod.exports = exports
  
  mod.status = STATUS.EXECUTED
  
  // Emit `exec` event
  
  emit("exec", mod)
  
  return exports
  
  /**
  
  * require返回mod.exports,供其他模块接收使用.
  
  * require返回的exports变量,模块要给exports变量赋值
  
  */
  
  seajs.require = function (id) {
  
  var mod = Module.get(Module.resolve(id))
  
  if (mod.status < STATUS.EXECUTING) {
  
  mod.onload()
  
  mod.exec()
  
  }
  
  return mod.exports

JS容易理解错误的地方的更多相关文章

  1. myeclipse中导入js报如下错误Syntax error on token "Invalid Regular Expression Options", no accurate correc

    今天在使用bootstrap的时候引入的js文件出现错误Syntax error on token "Invalid Regular Expression Options", no ...

  2. 什么是core dump linux下用core和gdb查询出现"段错误"的地方

    什么是core dump   linux下用core和gdb查询出现"段错误"的地方 http://blog.chinaunix.net/uid-26833883-id-31932 ...

  3. linux下用core和gdb查询出现"段错误"的地方【转】

    转自:http://blog.chinaunix.net/uid-30091091-id-5754288.html 原文地址:linux下用core和gdb查询出现"段错误"的地方 ...

  4. hadoop数据容易出现错误的地方

    最近在搞关于数据分析的项目,做了一点总结. 下图是系统的数据流向.容易出现错误的地方.1.数据进入hadoop仓库有四种来源,这四种是最基本的数据,简称ods,original data source ...

  5. 【转】Eclipse去除js(JavaScript)验证错误

    这篇文章主要是对Eclipse去除js(JavaScript)验证错误进行了介绍.在Eclipse中,js文件常常会报错.可以通过如下几个步骤解决 第一步:去除eclipse的JS验证:将window ...

  6. vue自定义指令(Directive中的clickoutside.js)的理解

    阅读目录 vue自定义指令clickoutside.js的理解 回到顶部 vue自定义指令clickoutside.js的理解 vue自定义指令请看如下博客: vue自定义指令 一般在需要 DOM 操 ...

  7. js面向对象理解

    js面向对象理解 ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是, ...

  8. eclipse中jquery.js文件有错误提示…

    eclipse中jquery.js文件有错误提示的解决办法 2013-04-06 19:18 浏览次数:382 由于jquery.js文件进行了压缩,压缩之后的语法eclipse无法完全识别,所以有错 ...

  9. eclipse去除js(JavaScript)验证错误

    第一步: 去除eclipse的JS验证: 将windows->preference->Java Script->Validator->Errors/Warnings-> ...

随机推荐

  1. .net core 发布到docker

    1. 安装docker-desktop,windows环境安装包 官方网站:https://www.docker.com/ 2.注册登陆Docker账号 安装成功后,在官方网站注册一个账号,使用账号登 ...

  2. Python协程中使用上下文

    在Python 3.7中,asyncio 协程加入了对上下文的支持.使用上下文就可以在一些场景下隐式地传递变量,比如数据库连接session等,而不需要在所有方法调用显示地传递这些变量.使用得当的话, ...

  3. DVWA中SQL回显注入

    一.SQL注入简介 1.1 SQL语句就是操作数据库的语句,SQL注入就是通过web程序在数据库里执行任意SQL语句. SQL 注入是一种常见的Web安全漏洞,攻击者利用这个漏洞,可以访问和修改数据, ...

  4. ctf题目writeup(3)

    题目地址: https://www.ichunqiu.com/battalion 1. 这个是个mp3,给的校验是为了下载下来的. 下来之后丢进audicity中 放大后根据那个音块的宽度来确定是 . ...

  5. 一笔画问题 南阳acm42(貌似没用到什么算法)

    一笔画问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下 ...

  6. 打印N个真值的所有真值组合

    例:N=2 (true,true),(false,true),(true,false),(false,false) #include<stdio.h> int count=0; void ...

  7. JAVA 泛型之类型擦除

    ★ 泛型是 JDK 1.5 版本引进的概念,之前是没有泛型的概念的,但泛型代码能够很好地和之前版本的代码很好地兼容. CollectionTest.java ---编译成CollectionTest. ...

  8. [Cracking the Coding Interview] 4.6 Successor 后继节点

    Write an algorithm to find the 'next' node(i.e. in-order successor) of a given node in a binary sear ...

  9. HBase 通过myeclipce脚本来获取固定columns(获取列簇中的列及对应的value值)

    第一步:关联Jar包 1. 配置hadoop-env.sh文件添加Hbase关联jar包 /opt/modules/hadoop-2.5.0-cdh5.3.6/etc/hadoop下编辑hadoop- ...

  10. 7.Mongodb复制(副本集)

    1.复制 什么是复制 复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性,并可以保证数据的安全性 复制还允许从硬件故障和服务中断中恢复数据 为什么要复制 数据备份 数据灾难恢复 ...