js混淆是什么意思(js 变量声明易混淆的几点知识)

本文目录
js 变量声明易混淆的几点知识
变量提升
变量与函数名提升优先级
js 作用域内有变量,这个很好理解,但有一些细节需要注意。
console.log(foo); // 函数function foo(){
console.log("函数声明");
}
console.log(foo); // 函数var foo = "变量";
console.log(foo); // 变量
当变量名与函数名同名,且都提升上去了,那最终结果是哪个声明起作用呢?
有两个知识点:
1. var foo;并不会覆盖之前的变量
2. 函数提升优先级比变量提升要高,且不会被变量声明覆盖,但是会被变量赋值覆盖,所以上面的代码实际上是
function foo(){ // 优先级最高,提升到最前面
console.log("函数声明");
}var foo; // 只提升声明,不提升赋值,且不能覆盖函数声明console.log(foo);
console.log(foo);
foo = "变量"; // 可以覆盖函数声明console.log(foo);
连等赋值的变量提升
var num1 = 1; function fn(num3){
console.log(num1); //output undefined
console.log(num3); //output 4
console.log(num4); //throw error “num4 is not defined”
console.log(num2); //throw error “num2 is not defined”
var num1 = num4 = 2; // js 连等赋值 num4 不会被提升
num2 = 3; // 没有 var 会挂载到全局作用域,但不会提升,所以之前会报错
var num3= 5;
}
fn(4);
if 判断内变量提升
if (true) {
function fn(){ return 1; }
}else {
if(false){
function fn(){ return 2; }
}
}
console.log(fn.toString());
console.log(fn())
以下是从找到这个例子的原文中摘抄的内容:chrome和ie一均为function fn(){ return 2;},而firefox中依然报错。
可见三者处理并不相同。ff中会提前变量的声明,但不会提前块级作用域中的函数声明。而chrome和ie下就会提前块级作用域中的函数声明,而且后面的声明会覆盖前面的声明。
函数的作用域内赋值
在js中,提到变量赋值,就要先说作用域,而作用域,在es6之前,只有函数才会形成独立的作用域,然后函数的嵌套形成了 js 的作用域链。子作用域内可以访问父级作用域内的元素。函数的作用域在函数确定的时候就已经确定,与调用无关。
// test1var x = 1;function foo(x) {
var x = 3; var y = function() {
x = 2;
console.log(x)
}
y();
console.log(x); return y
}var z = foo() // 2 2z() // 2
这段函数会输出三个 2 ,指向同一个 x,甚至,将 x 改为对象,就更明显了
// test2var x = "abc";function foo(x) {
var x = c; var y = function() {
return x;
} return y;
}var c = {a:1}var z = foo();
var b = z();
console.log(b === c); // true
上面例子中,foo 函数执行后,返回 y 函数并赋值给 z,z 指向 y 函数(函数体),此时,z 并不在 foo 函数的作用域内,在此作用域不能访问到 x,但 z 只是引用类型数据的一个指针,只是同 x 指向了同一个对象而已。而执行 z 函数,则会返回 x 的值,这个值是函数 y 作用域内访问到的 x 的值,是根据函数的书写位置确定的作用域,并不会因为调用位置不同,而改变变量的指向。
但是同时要注意,虽然函数作用域在函数写出来时就已经确定,但具体的值却跟调用的时机有关。
// test3var x = "abc";function foo(x) {
var x = c; var y = function() {
x.a++; return x;
} return y
}var c = {a:1}var z = foo();
console.log(z()) // {a: 2}console.log(z()) // {a: 3}console.log(z()) // {a: 4}
这个例子中,输出的三次都是同一个对象,但输出的值不同,这是因为输出的时候的值不同,这就和调用时的实际值有关了。
关于一段JS的解密,我混淆以后就还原不回来了.不知道怎么回事
看样子,这种混淆是不可逆的,是将变量名等,从有含义变成无含义,增加对方阅读代码的难度。如果没有新旧变量名的对照表,应该是无法还原的。

本文相关文章:
单片机unsigned什么意思(为什么单片机编程变量都要定义成unsigned)
2026年11月2日 19:30
access变量名的命名规则(在access中为什么y5不可作为变量名)
2026年9月14日 06:50
linux遍历目录(linux shell 遍历文件夹 并将结果保存 到变量)
2026年9月11日 22:40
全局变量存储在哪个区(全局变量的存储空间在什么时候分配分配在哪)
2026年7月19日 11:20
更多文章:
phpcms下载站(有没有phpcms v9的火车头采集入口)
2026年11月3日 15:10
十字路口红绿灯plc程序梯形图(简易欧姆龙PLC十字路口红绿灯梯形图)
2026年11月3日 14:50
js压缩图片最低能压缩多百分之多少?把vars.js压缩为vars.rar压缩文件怎么操作
2026年11月3日 11:10
lseek和fseek(read pread write pwrite fseek lseek是同一类函数吗)
2026年11月3日 08:30
字体大小在哪里调整(电脑字体大小在哪里调调电脑字体大小的方法)
2026年11月3日 04:40
网页页面设计的技巧有哪些?急求,jsp采用框架技术设计页面,如何写代码才能实现点击左侧框架内的链接,右侧框架内显示相应网页呢
2026年11月3日 03:00
selection是什么品牌(selection unique是什么葡萄酒)
2026年11月3日 01:50


