在这端代码执行的末尾,你会不会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. iOS中出现"Check dependenciesWarning: The Copy Bundle Resources build phase contains this target's Info.plist file..."的解决办法A

    出现场景   项目中移除info.plist ,后来又重新拖拽回来,同时勾选了Copy items if needed 解决办法 1.删除(删除时选择Remove Reference) 2.重新添加i ...

  2. 【ntp时间校准配置】

    Ntp(网络时间协议)是一种可以通过TCP/IP网络传播,其架构模式可分为C/S(客户端/服务器),PTP(对等),broatcast(广播), mutilbrocast(组播),无论在任何系统或设备 ...

  3. MySQL快速生成连续整数

    很多时候需要用到连续的id进行数据对比,如判断是否连续等问题.那么,生成连续整数的方式有多种,首先容易想到的是逐步循环,如果想生成1kw条记录,则需要循环1kw次进行插入,那么有没有其他方式呢,效率相 ...

  4. PHP一些常用魔术方法

    魔术方法                          调用方法                                     作用__set                   有两个 ...

  5. ZooKeeper(1)-入门

    一. Zookeeper工作机制 二.Zookeeper特点 三.Zookeeper数据结构 四.Zookeeper应用场景 统一命名服务 统一配置管理 统一集群管理 服务器动态上下线 软负载均衡

  6. Learning Experience of Big Data: Connect CentOs to Xshell and set Java environment on CentOS

    1.set up connections between vitural machine and Xshell: After we connect the virtural machine to ne ...

  7. Source Insight的使用

    1. source insight查看函数的上一级调用的位置(函数) --> 鼠标放在函数上,右键 选择 Jump To caller,就可以看到有哪些函数调用它了:

  8. webug学习(1)

    webug的题目,比较简单,拿来巩固一哈. 1. 一看就知道是注入漏洞了,啥也不说sqlmap直接开炮. 先-u 之后-u 网址 --current-db 获取当前网址的数据库 所以当前数据库就是 p ...

  9. Rmarkdown:输出html设置

    在Rstudio中可自行更改主题样式 --- title: "题目" author: "name" date: "`r format(Sys.time ...

  10. R语言学习笔记(十三):零碎知识点(36-40)

    36--diag() 如果它的参数是一个矩阵,它返回的是一个向量 如果它的参数是一个向量,它返回的是一个向量 如果它的参数是一个标量,它返回的是指定大小的单位矩阵 > diag(2) [,1] ...