IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 16、JavaScript进阶-作用域、函数 -> 正文阅读

[JavaScript知识库]16、JavaScript进阶-作用域、函数

一、作用域

【解释】: 规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问。

【分类】:

  • 局部作用域
  • 全局作用域

1.1 局部作用域

【分类】:

  • 数作用域
  • 块作用域

1、函数作用域

【解释】: 在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。

【示例】:

<script>
  // 声明 counter 函数
  function counter(x, y) {
    // 函数内部声明的变量
    let s = x + y;
    console.log(s); // 18
  }

  // 调用 counter 函数
  counter(10, 8);

  // 访问变量 s
  console.log(s); // 报错 外部无法访问函数内部的变量
</script>

【总结】:

  • 函数内部声明的变量,在函数外部无法被访问
  • 函数的参数也是函数内部的局部变量
  • 不同函数内部声明的变量无法互相访问
  • 函数执行完毕后,函数内部的变量实际被清空了

2、块作用域

【解释】: 在 JavaScript 中使用 {} 包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。

【示例】:

<script>
  {
    // age 只能在该代码块中被访问
    let age = 18;
    console.log(age); // 正常
  }
  
  // 超出了 age 的作用域
  console.log(age); // 报错
  
  let flag = true;
  if(flag) {
    // str 只能在该代码块中被访问
    let str = 'hello world!';
    console.log(str); // 正常
  }
  
  // 超出了 age 的作用域
  console.log(str); // 报错
  
  for(let t = 1; t <= 6; t++) {
    // t 只能在该代码块中被访问
    console.log(t); // 正常
  }
  
  // 超出了 t 的作用域
  console.log(t); // 报错
</script>

【常量值】: JavaScript 中除了变量外还有常量,常量与变量本质的区别是 【常量必须要有值且不允许被重新赋值】,常量值为对象时其属性和方法允许重新赋值。

【示例】:

<script>
  // 必须要有值
  const version = '1.0';
  // 不能重新赋值
  // version = '1.1';

  // 常量值为对象类型
  const user = {
    name: '小明',
    age: 18
  }

  // 不能重新赋值
  user = {};
  // 属性和方法允许被修改
  user.name = '小小明';
  user.gender = '男';
 
</script>

【总结之let、var、const】:

  • let 声明的变量会产生块作用域,var 不会产生块作用域
  • const声明的常量也会产生块作用域
  • 不同代码块之间的变量无法互相访问
  • 推荐使用 letconst
  • 开发中 letconst 经常不加区分的使用,如果担心某个值会不小被修改时,则只能使用 const 声明成常量。
关键字块级作用域变量提升初始值更改值通过window调用
let× √-×
const× √××
var×-

1.2 全局作用域

【解释】: <script> 标签和 js 文件的【最外层】就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。

【示例】:

<script>
  // 此处是全局
  
  function sayHi() {
    // 此处为局部
  }

  // 此处为全局
</script>
  • 全局作用域中声明的变量,任何其它作用域都可以被访问
<script>
    // 全局变量 name
    let name = '小明';
  
  	// 函数作用域中访问全局
    function sayHi() {
      // 此处为局部
      console.log('你好' + name);
    }

    // 全局变量 flag 和 x
    let flag = true;
    let x = 10;
  
  	// 块作用域中访问全局
    if(flag) {
      let y = 5;
      console.log(x + y); // x 是全局的
    }
</script>

【总结】:

  • window 对象动态添加的属性默认也是全局的,不推荐!
  • 函数中未使用任何关键字声明的变量为全局变量,不推荐!!!
  • 尽可能少的声明全局变量,防止全局变量被污染

1.3 作用域链

【解释】: 函数内部允许创建新的函数,f 函数内部创建的新函数 g,会产生新的函数作用域,由此可知作用域产生了嵌套的关系。作用域链本质上是底层的变量查找机制,在函数被执行时,会优先查找当前函数作用域中查找变量,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域

【示例】:

<script>
  // 全局作用域
  let a = 1;
  let b = 2;
	
  // 局部作用域
  function f() {
    let c;
    // 局部作用域
    function g() {
      let d = 'yo';
    }
  }
</script>
<script>
  // 全局作用域
  let a = 1;
  let b = 2;

  // 局部作用域
  function f() {
    let c;
    // let a = 10;
    console.log(a); // 1 或 10
    console.log(d); // 报错
    
    // 局部作用域
    function g() {
      let d = 'yo';
      // let b = 20;
      console.log(b); // 2 或 20
    }
    
    // 调用 g 函数
    g()
  }

  console.log(c); // 报错
  console.log(d); // 报错
  
  f();
</script>

【总结】:

  • 嵌套关系的作用域串联起来形成了作用域链
  • 相同作用域链中按着从小到大的规则查找变量
  • 子作用域能够访问父作用域,父级作用域无法访问子级作用域(就近原则)

1.4、闭包

【解释】: 闭包是一种比较特殊和函数,使用闭包能够访问函数作用域中的变量。

【好处】: 可以把一个变量使用范围延伸

【示例】:

<script>
  function foo() {
    let i = 0;

    // 函数内部分函数
    function bar() {
			console.log(++i);
    }

    // 将函数做为返回值
    return bar;
  }
  
  // fn 即为闭包函数
  let fn = foo();
  
  fn(); // 1
</script>

【总结】:

  • 闭包本质仍是函数,只不是从函数内部返回的
  • 闭包能够创建外部可访问的隔离作用域,避免全局变量污染
  • 过度使用闭包可能造成内存泄漏‘
  • 回调函数也能访问函数内部的局部变量。

1.5 变量提升

【解释】: 允许在变量声明之前即被访问

【示例】:

<script>
  // 访问变量 str
  console.log(str + 'world!');

  // 声明变量 str
  var str = 'hello ';
</script>

letvar都有提升,但是let定义的变量没有赋值之前是不可以使用、var可以使用是undefined

【总结】:

  • 变量在未声明即被访问时会报语法错误
  • 变量在声明之前即被访问,变量的值为 `undefined
  • let声明的变量不存在变量提升,推荐使用let`【也有人认为具有提升但是不赋值不能使用】
  • 变量提升出现在相同作用域当中
  • 实际开发中推荐先声明再访问变量

二、函数

2.1、函数提升

【解释】: 函数在声明之前即可被调用

【示例】:

<script>
  // 调用函数
  foo();

  // 声明函数
  function foo() {
    console.log('声明之前即被调用...');
  }

  // 不存在提升现象
  bar();
  var bar = function () {
    console.log('函数表达式不存在提升现象...');
  }
</script>

【总结】:

  • 函数提升能够使函数的声明调用更灵活
  • 函数表达式不存在提升的现象
  • 函数提升出现在相同作用域当中

2.2、函数参数

1、默认参数

【示例】:

<script>
  // 设置参数默认值
  function sayHi(name="小明", age=18) {
    document.write(`<p>我叫${name},我今年${age}岁了。</p>`);
  }
  // 调用函数
  sayHi();
  sayHi('小红');
  sayHi('小刚', 21);
</script>

【总结】:

  1. 声明函数时为形参赋值即为参数的默认值
  2. 如果参数未自定义默认值时,参数的默认值为 undefined
  3. 调用函数时没有传入对应实参时,参数的默认值被当做实参传入

2、动态参数

【解释】: arguments` 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参。

【示例】:

<script>
  // 求生函数,计算所有参数的和
  function sum() {
    // console.log(arguments);
    let s = 0;
    for(let i = 0; i < arguments.length; i++) {
      s += arguments[i];
    }
    console.log(s);
  }

  // 调用求和函数
  sum(5, 10); // 两个参数
  sum(1, 2, 4); // 两个参数
</script>

【注意】:

  • arguments是一个伪数组
  • arguments的作用是动态获取函数的实参

3、剩余参数

【语法及示例】:

<script>
  function config(baseURL, ...other) {
    console.log(baseURL);
    // other 是真数组,动态获取实参
    console.log(other);
  }

  // 调用函数
  config('http://baidu.com', 'get', 'json');
</script>

2.3、箭头函数

【解释】: 箭头函数是一种声明函数的简洁语法,它与普通函数并无本质的区别,差异性更多体现在语法格式上。

【示例】:

<script>
  // 箭头函数
  let foo = () => {
    console.log('^_^ 长相奇怪的函数...');
  }
  // 调用函数
  foo();
  
  // 更简洁的语法
  let form = document.querySelector('form');
  form.addEventListener('click', ev => ev.preventDefault());
</script>

【总结】:

  • 箭头函数属于表达式函数,因此不存在函数提升
  • 箭头函数只有一个参数时可以省略圆括号 `()
  • 箭头函数函数体只有一行代码时可以省略花括号 {},并自动做为返回值被返回
  • 箭头函数中没有 arguments,只能使用 ... 动态获取实参
  • 涉及到this的使用,不建议用箭头函数
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 10:44:41  更:2022-01-24 10:46:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 13:06:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码