在这端代码执行的末尾,你会不会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. PHP实现微信红包算法和微信红包的架构设计简介

    微信红包的架构设计简介: 原文:https://www.zybuluo.com/yulin718/note/93148 @来源于QCon某高可用架构群整理,整理朱玉华. 背景:有某个朋友在朋友圈咨询微 ...

  2. python 中 pynlpir错误 Cannot Open Configure file pynlpir\Data\Configure.xml 解决

    在用python做分词.数据处理的时候,想调用pynlpir库,pynlpir.open()时出现错误,更新一下授权文件还是错误, 仔细一看错误是:Cannot Open Configure file ...

  3. Python基础03

    while循坏while属于条件判断 条件满足====>执行 条件不满足====>退出循环 whlie循环格式 while 条件 : 执行语句 while 1 == 1: print(&q ...

  4. Python学习之模块基础

    模块就是程序 编写以下简单代码 print('hello python') 并将py文件保存在c盘的python(假设新建)文件下,通过pycharm的Terminal 或者windom命令窗口调出p ...

  5. 6-C++远征之封装篇[上]-学习笔记

    C++远征之封装篇(上) 课程简介 类(抽象概念),对象(真实具体) 配角: 数据成员和成员函数(构成了精彩而完整的类) 构造函数 & 析构函数(描述了对象的生生死死) 对象复制和对象赋值 ( ...

  6. 【转】谈谈 iOS 中图片的解压缩

    转自:http://blog.leichunfeng.com/blog/2017/02/20/talking-about-the-decompression-of-the-image-in-ios/ ...

  7. idea离线安装lombock插件

    技术交流群:233513714 安装过程 1.首先找到插件包 插件包可以在两个地方下载,分别是IDEA的官方插件仓库和GitHub里lombok-intellij-plugin仓库中的release包 ...

  8. jmeter添加自定义扩展函数之图片base64编码

    打开eclipse,新建maven工程,在pom中引入jmeter核心jar包: <!-- https://mvnrepository.com/artifact/org.apache.jmete ...

  9. ABP框架插件开发

    http://personball.com/abp/2017/08/21/abp-how-to-use-plugin

  10. Python网络编程(socketserver、TFTP云盘、HTTPServer服务器模型)

    HTTP协议? HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型.HTTP是一个无状态的协议. 通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了 ...