文档章节

JS容易理解错误的地方

器石_
 器石_
发布于 2018/12/19 11:36
字数 818
阅读 16
收藏 0

在这端代码执行的末尾,你会不会hi变量回事函数中的hi了?你会不会认为这不是按引用传递了? 对值传递和引用传递产生质疑了?

1   var hi = {};

2   function sayHello(hi) {
        
        // 这样来给hi赋值,声明的hi变量不会有任何变化,在函数外侧hi还是那个{}
        hi = {
            a: 'b'
        };    
        
        console.log('in function hi : ' + hi.a);
        alert(hi.a);
    }
    sayHello(hi);
    console.log('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('./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
  }

 

© 著作权归作者所有

共有 人打赏支持
上一篇: JavaScript之Object
下一篇: 位运算
器石_
粉丝 1
博文 39
码字总数 23452
作品 0
南京
后端工程师
私信 提问
JavaScript 对引擎、运行时、调用堆栈的概述理解

JavaScript 对引擎、运行时、调用堆栈的概述理解  随着JavaScript越来越流行,越来越多的团队广泛的把JavaScript应用到前端、后台、hybrid 应用、嵌入式等等领域。 这篇文章旨在深入挖掘Jav...

开元中国2015
2018/10/25
0
0
如何让程序员更容易的开发Web界面?重构SmartAdmin展示TinyUI框架

序言 如何让程序员更容易的开发Web界面,是一个持久的话题,所有的从事相关开发的公司都会碰到这个问题,并且被这个问题所深深困扰。 Tiny框架也不得不直视这个问题,确实来说,想解决这个问...

悠悠然然
2014/04/17
0
10
初看jQuery,比较dojo与jQuery的不同点

以下观点是建立在我初看jQuery,但并没有对jQuery详细理解的情况下。 可能随着后面对jQuery的使用,而增加更深的了解。也可能发现我当初的观点是错误的。 大体浏览了一下jQuery的文档,发现j...

xpbug
2012/08/18
0
0
JavaScript中的this指针 理论化this指针的定义

JavaScript现在应用之广泛,远超其他任何语言,只要是一个合格的网站应用,基本上多多少少都会有JS的存在。在JavaScript中,this的指向被不少Coder所不解,但其实JS中的this理解起来也是相当...

superwebmaster
2018/05/29
0
0
【译】深入理解 ES2015,第一趴:块作用域 let 和 const

原文地址:javascriptissexy.com/understandi… 原文作者:Dan Wellman Markdown 地址:github.com/Yangfan2016… 译者:Yangfan2016 ES2015 最大的特性之一就是有了一个全新的作用域。在这个...

Yangfan
01/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Windows 上安装 Scala

在安装 Scala 之前需要先安装 Java 环境,具体安装的详细方法就不在这里描述了。 您可以自行搜索我们网站中的内容获得其他网站的帮助来获得如何安装 Java 环境的方法。 接下来,我们可以从 ...

honeymose
今天
1
0
数据库篇多表操作

第1章 多表操作 实际开发中,一个项目通常需要很多张表才能完成。例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系...

stars永恒
今天
3
0
nginx日志自动切割

1.日志配置(Nginx 日志) access.log----记录哪些用户,哪些页面以及用户浏览器,IP等访问信息;error.log------记录服务器错误的日志 #配置日志存储路径:location / {      a...

em_aaron
昨天
5
0
java 反射

基本概念 RTTI,即Run-Time Type Identification,运行时类型识别。RTTI能在运行时就能够自动识别每个编译时已知的类型。   要想理解反射的原理,首先要了解什么是类型信息。Java让我们在运...

细节探索者
昨天
2
0
推荐转载连接

https://www.cnblogs.com/ysocean/p/7409779.html#_label0

小橙子的曼曼
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部