基础不牢地动山摇:JS逆向攻防对抗核心的博弈点在于对JS最基础部分的深刻理解和灵活应用——干货语法大全

基础不牢地动山摇:JS逆向攻防对抗核心的博弈点在于对JS最基础部分的深刻理解和灵活应用——语法大全

JS逆向攻防对抗核心的博弈点在于对JS最基础部分的深刻理解和灵活应用,偏门基础用法语法知道的越多,理解的越深刻,运用的越灵活才能赢。

1. JavaScript 基础

1.1 语法和数据类型letvarconst 的区别

JavaScript 的数据类型是理解变量和操作的基础。
letvarconst 是 JavaScript 中用于变量声明的关键字,它们之间有几个关键的区别:

  1. 作用域(Scope):
    • var 是函数作用域或全局作用域的,即使在代码块(如 for 循环或 if 语句)内部声明,它的作用域也是整个函数或全局.如果同时声明两次var也会报错。
    • letconst 是块级作用域的,意味着它们只在声明它们的代码块(如 for 循环、if 语句或任何其他类型的块)内可见。
function varTest() {
  var a = 10;
  if (true) {
    var b = 20; // 同一个作用域
    console.log(a); // 10
    console.log(b); // 20
  }
  console.log(b); // ReferenceError: b is not defined
}

function letTest() {
  let a = 10;
  if (true) {
    let b = 20; // 不同的作用域
    console.log(a); // ReferenceError: a is not defined
    console.log(b); // 20
  }
  console.log(a); // a is not defined
}
  1. 可变性(Mutability):
    • varlet 允许变量重新赋值。
    • const 声明的变量是不可变的,这意味着你不能重新分配新的值给这个变量,但如果你声明的是一个对象或数组,你可以修改对象的属性或数组的元素。
var message = 'Hello';
message = 'Hi'; // 允许重新赋值

let count = 1;
count = 2; // 允许重新赋值

const name = 'ln';
name = 'AI'; // TypeError: Assignment to constant variable.

const person = { name: 'ln' };
person.name = 'AI'; // 允许修改对象的属性
  1. 全局对象属性(Global Object Property):
    • 使用 var 在全局作用域声明的变量会成为全局对象的属性(在浏览器中是 window 对象)。
    • 使用 letconst 在全局作用域声明的变量不会成为全局对象的属性。
var globalVar = 'I am a global variable';
console.log(window.globalVar); // 'I am a global variable'

let globalLet = 'I am not a global object property';
console.log(window.globalLet); // undefined
  1. 提升(Hoisting):
    • var 声明会被提升到它们所在作用域的顶部,但初始化不会被提升。
    • letconst 声明也会被提升,但它们不会被初始化,直到它们被明确声明。这意味着在声明之前访问这些变量会抛出一个 ReferenceError
console.log(varTest); // undefined (只提升了声明)
var varTest = 10;

console.log(letTest); // ReferenceError: Cannot access 'letTest' before initialization
let letTest = 20;

console.log(constTest); // ReferenceError: Cannot access 'constTest' before initialization
const constTest = 30;

了解这些区别对于编写可维护和清晰的 JavaScript 代码至关重要。通常推荐使用 letconst 来声明变量,因为它们提供了块级作用域,有助于避免意外的作用域问题。使用 const 可以保证变量不可变性,有助于减少错误。

1.2 操作符和表达式

操作符是执行程序逻辑和计算的构建块。

// 算术运算
let total = 5 + 3;

// 字符串连接
let greeting = 'Hello, ' + name + '!';

// 逻辑运算
let isApproved = isDebugging && count > 5;
1.3 控制流

控制流语句控制程序的执行顺序。

// if...else 语句
if (count > 0) {
  console.log('Count is positive.');
} else {
  console.log('Count is not positive.');
}

// for 循环
for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i]);
}

// break 和 continue
for (let i = 0; i < 10; i++) {
  if (i === 5) break;
  if (i % 2 === 0) continue;
  console.log(i);
}


var value = 1;
switch (value) {
  case 1: {
    let value = 'Value is 1'; // 这里的let声明了一个块作用域的新变量
    console.log(value);
    break;
  }
  case 2:
    console.log('Value is 2');
    break;
  default:
    console.log('Value is not 1 or 2');
}


2. 函数和作用域

2.1 函数定义和调用

函数是封装代码以供重复使用的结构。


// 函数表达式
const sayGoodbye = function(name) {
  console.log(`Goodbye, ${name}!`);
};

2.2 自执行函数

自执行函数(Immediately Invoked Function Expression,简称IIFE)是一种在定义后立即执行的JavaScript函数表达式。这种模式有几个关键特点:

  1. 匿名性:自执行函数通常是匿名的,这意味着它们没有名字。
  2. 立即执行:函数定义后会立即执行,不需要显式调用。
  3. 作用域限制:自执行函数提供了一个独立的作用域,有助于避免污染全局命名空间。

无参数的自执行函数

(function() {
  console.log('This is an IIFE.');
})();

带参数的自执行函数

自执行函数也可以接受参数:

(function(greeting) {
  console.log(greeting);
})('Hello, IIFE!');

为什么使用自执行函数

  1. 避免命名冲突:自执行函数是匿名的,可以避免命名冲突。
  2. 创建局部变量:自执行函数允许在其中声明局部变量,这些变量在函数外部不可访问。
  3. 模块模式:自执行函数可以用于JavaScript模块模式,以保持代码的封装性。
  4. 控制执行时机:立即执行的特性使得自执行函数非常适合用于初始化代码。

模块模式

自执行函数经常用于JavaScript模块模式,以提供私有作用域:

const myModule = (function() {
  const privateVar = 'I am private';

  return {
    publicMethod: function() {
      console.log('Accessing private variable:', privateVar);
    }
  };
})();

myModule.publicMethod(); // 'Accessing private variable: I am private'

在上面的例子中,privateVar 是一个私有变量,只能在自执行函数内部访问,而 publicMethod 是公共接口的一部分,可以从外部调用。

避免全局变量

自执行函数可以避免创建全局变量:

(function() {
  let localVar = 'I am local to this IIFE';
})();

console.log(localVar); // ReferenceError: localVar is not defined
箭头函数

自执行函数同样可以使用箭头函数的语法:


// 箭头函数
const greet = (name) => `Hello, ${name}!`;

(() => {
  console.log('Arrow function IIFE.');
})();
2.2 闭包和高阶函数

闭包提供了一种保护变量作用域的方式,而高阶函数可以接受或返回函数。

// 闭包
function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

const addFive = makeAdder(5);
console.log(addFive(3)); // 8

// 高阶函数
function map(numbers, func) {
  return numbers.map(n => func(n));
}

const squares = map(numbers, n => n * n);
console.log(squares);

3. 对象和原型链

3.1 对象字面量和原型

对象是属性和方法的集合,原型链是 JavaScript 继承的核心。

// 对象字面量
let car = {
  brand: 'Tesla',
  model: 'Model S',
  start: function() {
    console.log(`${this.model} is starting.`);
  }
};

car.start(); // 'Model S is starting.'

// 原型链
function Vehicle(make, model) {
  this.make = make;
  this.model = model;
}

Vehicle.prototype.displayInfo = function() {
  console.log(`Make: ${this.make}, Model: ${this.model}`);
};

let myCar = new Vehicle('Tesla', 'Model S');
myCar.displayInfo(); // 'Make: Tesla, Model: Model S'
3.2 构造函数和 new

构造函数用于创建特定类型的对象实例。

// 构造函数
function Animal(species, sound) {
  this.species = species;
  this.sound = sound;
}

Animal.prototype.makeSound = function() {
  console.log(`${this.species} says ${this.sound}.`);
};

let dog = new Animal('Dog', 'Bark');
dog.makeSound(); // 'Dog says Bark.'

4. 异步编程

4.1 回调函数

回调函数是异步编程的基础,用于处理完成的异步操作。

// 回调函数
function onSuccess(data) {
  console.log('Data received:', data);
}

function onDataReceived(error, data) {
  if (error) throw error;
  onSuccess(data);
}

// 模拟异步数据接收
setTimeout(() => onDataReceived(null, { info: 'asynchronous data' }), 1000);
4.2 Promises 和 Async/Await

Promises 提供了一种更优雅的异步编程方式,而 async/await 进一步简化了代码。

// Promises
const delayedData = new Promise((resolve) => {
  setTimeout(() => resolve('Promise data'), 1000);
});

delayedData.then(onSuccess).catch(error => console.error(error));

// Async/Await
async function fetchData() {
  try {
    const data = await delayedData;
    console.log('Fetched data:', data);
  } catch (error) {
    console.error(error);
  }
}

fetchData();

5. 模块和作用域

5.1 CommonJS 和 ES6 Modules

模块化是现代 JavaScript 开发的关键部分,它帮助我们组织和管理代码。

// CommonJS 模块
const myUtils = require('./utils');
myUtils.doSomething();

// ES6 模块
import { doSomething } from './utils';
doSomething();

结论

JavaScript 逆向工程要求我们不仅要理解语言的表面语法,还要深入到语言的内部机制。掌握从基础语法到高级概念的知识,是每个逆向工程师的必备技能。通过不断学习和实践,我们可以提高自己的技术水平,更好地应对各种代码挑战。

注意

本文提供的代码示例仅用于教育目的,不应用于任何非法逆向工程活动。请确保在进行逆向工程时遵守相关法律法规。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值