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的解密,我混淆以后就还原不回来了.不知道怎么回事
看样子,这种混淆是不可逆的,是将变量名等,从有含义变成无含义,增加对方阅读代码的难度。如果没有新旧变量名的对照表,应该是无法还原的。

更多文章:
timestamp without time zone(Postgresql中to_date()函数使用问题)
2026年9月7日 09:40
下载mysql的步骤(win10安装mysql的步骤和方法)
2026年9月7日 04:10
checked in(check in和check out的区别)
2026年9月7日 01:20
java经典上机编程题(java上机题 请问这道题应该怎么写)
2026年9月7日 01:10
影视剧中有哪些剧情颠覆了你的三观?金庸的武侠小说《白马啸西风》为什么没有被拍成电影或者电视剧
2026年9月7日 00:30
mysql varchar和char的区别(mysql中char、varchar、nvarchar区别)
2026年9月7日 00:10
linux命令的选项和参数(linux为什么要有参数和选项)
2026年9月6日 20:20





