V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
maomaomao001
V2EX  ›  JavaScript

javascript 有没有办法从外部访问(修改) 闭包里的 属性

  •  
  •   maomaomao001 · 2016-12-04 17:04:12 +08:00 · 5081 次点击
    这是一个创建于 2692 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如这样的 一个 闭包作用于

    $(function(){
    	var v1 = "想要修改(访问)这个"
    	
    	function pv1(){
    		console.log(v1)
    	}
    	
    })
    
    // 有没有什么奇怪的方法在这个作用域拿到 $(function(){} 里的属性?
    
    [v1] = "修改的值"
    
    [pv1](); // 打印出'修改的值' 就对了
    
    

    javascript 能做到这一点吗?

    14 条回复    2016-12-05 13:30:55 +08:00
    bdbai
        1
    bdbai  
       2016-12-04 17:31:28 +08:00 via Android
    闭包里面的变量外面不能访问。你可以让闭包返回一个函数,调用函数修改 v1 的值。
    maomaomao001
        2
    maomaomao001  
    OP
       2016-12-04 17:35:48 +08:00
    @bdbai 嗯,我知道按常理是不能访问的,所以就想问问 有没有比较奇特的方法

    PS: 你用谷歌浏览器断点调试的时候 就可以修改闭包里面的变量
    bdbai
        3
    bdbai  
       2016-12-04 17:43:28 +08:00 via Android
    @maomaomao001 让闭包返回一个函数,外面调用函数修改 v1 的值。
    tux
        4
    tux  
       2016-12-04 17:46:08 +08:00
    刚好碰到同样问题,也没找到办法
    但是有一个说法是在 JS 文件加载之前阻止,然后替换成一个修改过的
    也就是 JS 劫持
    luoway
        5
    luoway  
       2016-12-04 22:38:26 +08:00
    1L 正解
    sensui7
        6
    sensui7  
       2016-12-04 23:20:13 +08:00 via iPhone
    所以你其实是想修改一个局部变量。

    如果是简单数据类型,修改没意义吧,值引用的。如果是对象,确实可以通过闭包修改。然而正确的做法不是在对象里做接口吗。
    结论是你的想法就很独特
    maomaomao001
        7
    maomaomao001  
    OP
       2016-12-05 00:43:53 +08:00 via Android
    @sensui7 主要是想,从外部入侵别人的代码~~~实现修改~~~似乎除了拦截 js 并修改,别无它法~~
    lalalanet
        8
    lalalanet  
       2016-12-05 07:44:34 +08:00 via iPhone
    在老版本浏览器里,你可以把 console.log 重写
    itkdqwzero
        9
    itkdqwzero  
       2016-12-05 08:27:26 +08:00 via Android
    用 getter 与 setter
    ianva
        10
    ianva  
       2016-12-05 10:52:06 +08:00
    如果是特殊原因的话,用 hack 点的方法,将这段代码 toString 后在代码里插入相应的 get 方法,然后 eval 就可以跑了
    ianva
        11
    ianva  
       2016-12-05 10:59:51 +08:00
    当然如果不好 toString 的话可以直接拿 script 标签里的文本
    如果是写在 script 标签内的可以通过 innerHTML 拿
    如果是 js 文件可以用 $.get("hello.js",function(text){alert(text)}) 的方式拿到
    后面做匹配插入文本和 eval 就很简单了
    zhuangzhuang1988
        12
    zhuangzhuang1988  
       2016-12-05 13:05:20 +08:00
    maomaomao001
        13
    maomaomao001  
    OP
       2016-12-05 13:14:19 +08:00 via Android
    @ianva 这样是可以跑~~~到是源代码里的环境并没有变啊~~比源代码设置了一个定时器~~~定时比对某个变量~~~
    你 eval 运行后只能是一个新的环境,新的定时器,原先的还在继续执行着
    ianva
        14
    ianva  
       2016-12-05 13:30:55 +08:00
    不让他运行的方法太多了,举个例子,比如这个函数,是基于 domready 执行的晚的很,依赖于 jquery ,你在这个代码之前将 var $ = function(){} 就解决问题了,需要的时候引入 jquery ,这是一种方案,思路是不运行咯,当然有各种手段
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1068 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 19:07 · PVG 03:07 · LAX 12:07 · JFK 15:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.