【H2O2|全栈】JS入门知识(五)

目录

JS

前言

准备工作

数组API(一)

API概念

数组常见API(一)

arguments

作用域

概念

全局作用域

局部作用域

块级作用域

变量的作用域

作用域链

案例

预解析

概念

变量预解析

函数预解析

案例

对象

概念

优点

属性和属性值

创建对象

遍历对象

结束语


JS

前言

本系列博客主要分享JavaScript的基础语法知识,本期为第五期,包含一些简单的js语法。今天的内容主要包括数组的常用API,作用域,变量,预解析以及对象的相关内容。

与HTML和CSS相比,JS加入了很多逻辑性的元素在里面,所以需要一定的逻辑思维能力,要求能够整合一些知识。如果遇到不理解之处,可以参阅同系列之前的章节。

准备工作

软件:【参考版本】Visual Studio Code

插件(扩展包):Open in browser, Live Preview, Live Server, Tencent Cloud AI Code Assistant, htmltagwrap

浏览器版本:Chrome

系统版本: Win10/11/其他非Windows版本

*我的电脑是Win10的版本,仅供参考*

数组API(一)

API概念

API,英文全称为Application Programming Interface,即应用程序编程接口。 

通常来说,API是软件系统中的一组预定义函数、协议或规则,用于不同软件应用程序之间的通信和数据交换

之前我们知道,可以使用  arr.length  调用数组的长度,类似的,我们也可以使用相同的方式调用数组的API。

不过需要注意,API通常为函数或者方法,因此在调用时不要忘记小括号和必要的参数(如果有)。

数组常见API(一)

今天主要来讲部分常用的数组API,先列在表格里——

API作用
splice(index, number)在数组的index位置开始删除number个元素
splice(index, number, content)在数组的index位置开始删除number个元素,并且替换上content的内容
unshift(item)在数组开头增加指定元素
shift()在数组开头删除一个元素
push(item)压栈,即在数组的末尾增加指定元素
pop()弹栈,即在数组的末尾删除一个元素
slice(start, end)从数组中截取指定左闭右开区间(索引)内的元素
arr1.concat(arr2)在指定的数组的末尾拼接另一个数组
join("separator")将数组转化为字符串,并且在元素之间添加分隔符separator
sort()默认升序排序,元素有多个字符时,取数组元素的第一个字符进行排序

sort(function(a, b) {

        return a - b

})

内置匿名函数进行排序,以 a - b 为正值设置升序排序,此时 b - a 为负值,即设置降序排序
reverse()将数组内容翻转

arguments

arguments是一种类数组,它有数组的索引和长度,但是没有数组的API。

在函数中,arguments是默认有的,可以用来接收任意长度的数组。

作用域

概念

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突

在es6之前,JS有两种作用域——全局作用域局部作用域

在es6之后,还有一种作用于 {} 内的作用域——块级作用域

全局作用域

全局作用域指的是所有代码执行的所在的整个环境,通常来说,这个环境是window

局部作用域

局部作用域指的是作用于函数内部的代码环境,所以也可以叫函数作用域。

块级作用域

{} 内定义的某些变量,我们希望它只在 {} 中使用,即在块级作用域里使用。

在es6中,使用let和const声明定义的变量,只能在 {} 中使用。

常见的块级作用域有  if()  for()  等。

变量的作用域

根据作用域的不同,变量可以分为两种——全局变量局部变量

全局变量在代码的任何位置都可以使用,在全局作用域下 var 声明的变量都是全局变量。

特殊情况下,在函数内不使用 var 声明的变量也是全局变量(写法不规范,所以不建议使用)。

局部变量只能在该函数内部使用,在函数内部 var 声明的变量是局部变量。

函数的形参实际上就是一种局部变量。

两类变量的区别是:

  • 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
  • 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间

作用域链

如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域;

根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链

作用域链的原则为就近原则,即选取最近的元素作为当前使用的元素。

案例

Q:现在,有下面这串代码——

var a = 1;
var b = '11';
function fn1() {var a = 2;var b = '22';fn2();function fn2() {var a = 3;fn3();function fn3() {var a = 4;console.log(a); //a的值 ?console.log(b); //b的值 ?}}
}
fn1();

请问输出的a和b的值是多少?

A:我们使用一张图来分析上述代码的作用域链——

所以,输出应当是4和'22'。

Q:对于下面的代码,输出的值应当是多少?

var a = 10function fn1() {var a = 20fn2()
}function fn2() {console.log(a)
}

A:对于  fn2()  而言,虽然它在  fn1()  中被调用了,但是实际上它是被声明在全局中的,所以作用域是window,因此输出值为10。

预解析

概念

JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。

JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析代码执行

  • 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提前声明或者定义,预解析也叫做变量提升函数提升
  • 代码执行: 从上到下执行JS语句。

注意:预解析会把变量和函数的声明在代码执行之前执行完成。

变量预解析

变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升

函数预解析

函数的声明会被提升到当前作用域的最上面,但是不会调用函数。

案例

Q:对于下面的代码,输出的结果是什么?

console.log(num)
var num = 10fn1()
function fn1() {console.log('打印')
}fn2()
var fn2 = function() {console.log('想不到吧')
}

A:由于变量的值不会提升,所以第一个是默认var num但是未赋值,结果为输出undefined

由于命名函数可以提升,相当于在fn1()之前实质上已经声明函数并在该语句完成调用,结果为输出打印

匿名函数相当于变量,该段代码执行之前,会做变量声明提升,fn在提升之后的值是undefined;而fn调用是在fn被赋值为函数体之前,此时fn的值是undefined,所以无法正确调用,结果为报错 fn is not a function

对象

概念

在 JavaScript 中,对象是一组无序的相关属性方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。

  • 属性:事物的特征,在对象中用属性来表示(常用名词表示)
  • 方法:事物的行为,在对象中用方法(函数)来表示(常用动词表示)

以一部手机为对象,那么它的属性和方法应当是——

优点

保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。

如果要保存一个人的完整信息呢?

例如,将“张三”的个人的信息保存在数组中的方式为——

var arr = [‘张三’, ‘男', 128, 154]

上述例子中用数组保存数据的缺点是:数据只能通过索引值访问,开发者需要清晰的清除所有的数据的排行才能准确地获取数据,而当数据量庞大时,不可能做到记忆所有数据的索引值。

为了让更好地存储一组数据,对象应运而生:对象中为每项数据设置了属性名称,可以访问数据更语义化,数据结构清晰,表意明显,方便开发者使用。

如果使用对象来表述上述信息,应当如下——

var obj = {"name":"张三","sex":"男","age":128,"height":154
}

属性和属性值

对象中包含了表达这个具体事物(对象)的属性和方法,采取键值对的形式表示。

  • 键:相当于属性名,即对象中存储具体数据的项
  • 值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等),对象方法即对象中存储函数的项

比如,之前在为张三设置名字属性时,使用的就是下面的键值对——

name: "张三",

这里也给一个值为函数的情况吧——

sayHello : function(){alert('大家好啊~');}

访问对象的属性

  • 对象里面的属性调用 : 对象.属性名 ,这个小点 . 就理解为“ 的 ”
  • 对象里面属性的另一种调用方式 : 对象[‘属性名’],注意方括号里面的属性必须加引号 

示例代码如下——

console.log(obj.name)     // 调用名字属性
console.log(obj['name'])  // 调用名字属性

调用对象的方法

  • 对象里面的方法调用:对象.方法名() ,注意这个方法名字后面一定加括号
  • 也可以利用函数名调用

示例代码如下——

obj.fn()
obj["fn"]()

小结

属性是对象的一部分,而变量不是对象的一部分,变量是单独存储数据的容器

  • 变量:单独声明赋值,单独存在
  • 属性:对象里面的变量称为属性,不需要声明

方法是对象的一部分,函数是单独封装操作的容器

  • 函数:单独存在的,通过“函数名()”的方式就可以调用
  • 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用 

创建对象

创建对象通常来说有三种方式——字面量new构造函数

使用字面量创建

使用字面量创建的参考代码如下——

var obj1 = {}

这种方式在创建时即可添加属性和属性值,示例代码如下——

var obj = {name : 'pink',age : 18,sex : '男',sayHello : function(){alert('大家好啊~');}
};

使用new Object()创建

该方式用于创建一个空的对象,参考代码如下——

var obj2 = new Object();

实质上,Object()内置了一个构造函数,利用构造函数创建了一个新对象。

为该方法创建的对象赋值的方法示例如下——

obj2.name = 'pink';
obj2.age = 18;
obj2.sex = '男';
obj2.sayHello = function(){alert('大家好啊~');
}

注意以下三个要点:

  • Object() :第一个字母大写
  • new Object() :需要 new 关键字
  • 使用的格式:对象.属性 =  值;

使用构造函数创建

构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

使用构造函数的封装格式如下——

function 构造函数名(形参1,形参2,形参3) {this.属性名1 = 参数1;this.属性名2 = 参数2;this.属性名3 = 参数3;this.方法名 = 函数体;
}

使用构造函数调用的参考代码如下——

var obj3 = new 构造函数名(实参1,实参2,实参3)

以上代码中,obj即接收到构造函数创建出来的对象。

注意事项

  • 构造函数约定首字母大写
  • 函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。
  • 构造函数中不需要 return 返回结果
  • 当我们创建对象的时候,必须用 new 来调用构造函数
  • 构造函数,如 Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class);创建对象,如 new Stars(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化 

new关键字的作用

  • 在构造函数代码开始执行之前,创建一个空对象;
  • 修改this的指向,把this指向创建出来的空对象;
  • 执行函数的代码
  • 在函数完成之后,返回this---即创建出来的对象  

遍历对象

for...in 语句用于对数组或者对象的属性进行循环操作。

示例代码如下——

for (变量 in 对象名字) {// 在此执行代码
}

语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key

遍历对象获取属性和属性值的示例代码如下——

for (var k in obj) {console.log(k);      // 这里的 k 是属性名console.log(obj[k]); // 这里的 obj[k] 是属性值
}

扩充知识

我们知道,数组实质上也是一种对象,所以我们也可以用相同的 for ... in 方式对数组进行遍历——

for (var i in arr) {console.log(arr[i])
}

此时的i是索引值

此外,我们还可以使用 for ... of 方式对数组进行遍历——

for (var item in arr) {console.log(item)
}

此时的item是数组中的元素

结束语

本期的内容到这里就结束了,主要是js的数组的常用API,作用域,预解析以及对象的相关内容。在后续的本系列博客中,我会继续更新js的基础语法知识,并适当地配合上一些案例。

在全栈领域,博主也只不过是一个普通的萌新而已。本系列的博客主要是记录一下自己学习的一些经历,然后把自己领悟到的一些东西总结一下,分享给大家。

文章全篇的操作过程都是笔者亲自操作完成的,一些定义性的文字加入了笔者自己的很多理解在里面,所以仅供参考。如果有说的不对的地方,还请谅解。

==期待与你在下一期博客中再次相遇==

——还在漏气的【H2O2】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453394.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【RTT-Studio】详细使用教程十七:FreeModbus通信--LCD

文章目录 一、简介二、Modbus通信三、LCD通信四、配置FreeModbus通信协议四、完整代码五、测试验证 一、简介 Modbus协议是一种用于工业控制的网络通讯协议,可以片面的理解为,Modbus协议一种机器与机器之间进行数据、信息传递的一种格式规范。   Modbu…

PostgreSQL的学习心得和知识总结(一百五十五)|[performance]优化期间将 WHERE 子句中的 IN VALUES 替换为 ANY

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库…

《MYSQL实战45讲 》 优化器如何选择索引?

SHOW VARIABLES LIKE long_query_time; set long_query_time0 优化器如何选择索引? 1.扫描的行数 估计出各个索引大致的要扫描的行数,行数越少,效率越高。 索引的基数也叫区分度,就是这个索引所在的字段上不同的值又多少个。优…

MySQL【知识改变命运】06

前言:在05这节数据结构里面,我们知道select * from 这个操作很危险,如果数据库很大,会把服务器资源耗尽,接下来提到的查询可以有效的限制返回记录 1:分页查询 分页查询可以有效控制一次查询出来的结果集的…

数据结构与集合源码

目录 一、数据结构 1.1 数据结构概念 1.2 研究对象 1.3 常见存储结构 1.3.1 数组 1.3.2 链表 1.单向链表 2.双向链表 1.3.3 二叉树 1.3.4 栈(FILO,先进后出) 1.3.5 队列(FIFO,先进先出) 二、集合…

基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet模型【pytorch框架+python源码】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示: 基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet【pytorch框架,python,tkinter】_哔哩哔哩_bilibili (一)简介 基于卷积神…

Java设计模式梳理:行为型模式(策略,观察者等)

行为型模式 行为型模式关注的是各个类之间的相互作用,将职责划分清楚,使得我们的代码更加地清晰。 策略模式 策略模式太常用了,所以把它放到最前面进行介绍。它比较简单,我就不废话,直接用代码说事吧。 下面设计的…

软件架构之构件复用技术

简介 软件架构复用 在应用软件系统的开发过程中,通常包含以下几个关键阶段:需求分析、设计、编码、测试和维护。在这些阶段中,复用技术均可以得到有效应用。特别是,软件架构复用作为一种大粒度、高抽象级别的复用方式&#xff0…

55 | 享元模式(下):剖析享元模式在Java Integer、String中的应用

上篇文章,我们通过棋牌游戏和文本编辑器这样两个实际的例子,学习了享元模式的原理、实现以及应用场景。用一句话总结一下,享元模式中的“享元”指被共享的单元。享元模式通过复用对象,以达到节省内存的目的。 今天,我…

[PHP]重复的Notice错误信息

<?php $a []; var_dump($a[name]);执行结果&#xff1a; 原因&#xff1a; display_errors和error_reporting都打开了Notice错误信息

线性回归实现

1.从数据流水线、模型、损失函数、小批量随机梯度下降优化器 %matplotlib inline import random import torch from d2l import torch as d2l 2.根据带有噪声的线性模型构造人造数据集。使用线性模型参数w [2,-3.4]T、b 4.2和噪声项ε生成数据集及标签 y Xw b ε def …

windows 上验证请求接口是否有延迟

文件名&#xff1a;api_request_script.bat &#xff0c;直接右键点击执行即可。 echo off setlocal:: 配置:: 替换为实际接口URL set "logFilelog.txt" set "errorLogFileerror_log.txt" set "interval3" :: 请求间隔&#xff08;秒&#xff…

React之组件渲染性能优化

关键词&#xff1a; shouldComponentUpdate、PureComnent、React.memo、useMemo、useCallback shouldComponentUpdate 与 PureComnent shouldComponentUpdate 与 PureComnent 用于类组件。虽然官方推荐使用函数组件&#xff0c;但我们依然需要对类组件的渲染优化策略有所了解…

面经汇总——第一篇

1. int数据类型做了什么优化 Java在处理整数类型时&#xff0c;进行了多种优化&#xff0c;主要体现在编译器层面和JVM层面&#xff0c;目的是提高性能、减少内存开销。 常量池优化 Java中的Integer类有一个缓存机制&#xff0c;对于值在-128到127之间的int数字&#xff0c;Int…

springBoot集成nacos注册中心以及配置中心

一、安装启动nacos 访问&#xff1a;http://127.0.0.1:8848/nacos/index.html#/login 二、工程集成nacos 1、引入依赖 我这里搭建的父子工程哈&#xff0c;在子工程引入 <dependencies><!-- SpringBoot Web --><dependency><groupId>org.sp…

代码审计-Python Flask

1.Jinjia2模版注入 Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug &#xff0c;模板引擎则使用 Jinja2。jinja2是Flask作者开发的一个模板系统&#xff0c;起初是仿django模板的一个模板引擎&#xff0c;为Flask提供模板支持&#xff0c;由于…

MySQL-30.索引-介绍

一.索引 为什么需要索引&#xff1f;当我们没有建立索引时&#xff0c;要在一张数据量极其庞大的表中查询表里的某一个值&#xff0c;会非常的消耗时间。以一个6000000数据量的表为例&#xff0c;查询一条记录的时间耗时约为13s&#xff0c;这是因为要查询符合某个值的数据&am…

RabbitMQ系列学习笔记(八)--发布订阅模式

文章目录 一、发布订阅模式原理二、发布订阅模式实战1、消费者代码2、生产者代码3、查看运行结果 本文参考&#xff1a; 尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq RabbitMQ 详解 Centos7环境安装Erlang、RabbitMQ详细过程(配图) 一、发布订阅模式原理 在开发过程中&…

SpringBoot+MyBatis+MySQL项目基础搭建

一、新建项目 1.1 新建springboot项目 新建项目 选择SpringBoot&#xff0c;填写基本信息&#xff0c;主要是JDK版本和项目构建方式&#xff0c;此处以JDK17和Maven举例。 1.2 引入依赖 选择SpringBoot版本&#xff0c;勾选Lombok&#xff0c;Spring Web&#xff0c;MyBa…

UI自动化测试 —— web端元素获取元素等待实践!

前言 Web UI自动化测试是一种软件测试方法&#xff0c;通过模拟用户行为&#xff0c;自动执行Web界面的各种操作&#xff0c;并验证操作结果是否符合预期&#xff0c;从而提高测试效率和准确性。 目的&#xff1a; 确保Web应用程序的界面在不同环境(如不同浏览器、操作系统)下…