likes
comments
collection
share

【javaScript】基础梳理

作者站长头像
站长
· 阅读数 36

简介

  1. javascript不仅可以在浏览器端执行,也可以在服务端执行,甚至可以在任何装载了javascript引擎的设备中执行
  2. 不同的引擎有不同的代号,比如chrome,Opera和edge的引擎v8,Firefox的引擎SpiderMonkey
  3. 引擎的工作原理:读取脚本,将脚本解析成计算机语言(编译),然后机器执行代码,引擎会对每个流程进行优化

浏览器中的javascript

浏览器中的js能给网页添加或修改内容,响应用户行为,向远程服务器发送请求,下载上传文件,设置读取cookie,记住客户端数据等,但需要注意,出于对用户信息安全,浏览器js的能力是受限的,这是为了防止恶意获取用户信息或损害用户数据,所以浏览器中的js读、写、复制和执行硬盘上的任意文件,它没有直接访问操作系统的功能,浏览器是允许对文件进行一些相关操作的,但也是受限的,需要用户做出特定的行为,比如拖放文件,用过input选择文件,总之是需要获得用户明确许可的,此外,不同窗口之间(不同源)是不能通信的,这也是为了用户信息的安全

script

  1. 一般来说,只有最简单的脚本才嵌入到 HTML 中。更复杂的脚本存放在单独的文件中,使用独立文件的好处是,浏览器会下载它,然后将它保存到浏览器的缓存中,之后其他页面想要相同的脚本就会从缓存中获取,而不是下载它。所以文件实际上只会下载一次,这可以节省流量,并使得页面更快
  2. script指定了src,标签内容就会被忽略,所以script不能同时有src和内部代码

alert、prompt 和 confirm

  1. alert显示信息,prompt显示信息要求用户输入文本。点击确定返回文本,点击取消或按下 Esc 键返回null,confirm显示信息等待用户点击确定或取消。点击确定返回 true,点击取消或按下 Esc 键返回 false
  2. 这些方法都是模态的,它们暂停脚本的执行,并且不允许用户与该页面的其余部分进行交互,直到窗口被解除
  3. 模态窗口的确切位置由浏览器决定。通常在页面中心,外观也是由浏览器决定的,我们不能修改它

数据类型

javascript有八大数据类型,前七种为基本数据类型(原始数据类型),而object为复杂数据类型 原始数据类型:

  1. number:用于任何类型的数字:整数或浮点数,在 ±(253-1) 范围内的整数
  2. bigint:用于任意长度的整数
  3. string:字符串
  4. boolean: 用于 true 和 false
  5. null: 用于未知的值
  6. undefined:用于未定义的值
  7. symbol:用于唯一的标识符 复杂数据类型:object 用于更复杂的数据结构

typeof

typeof 运算符查看存储在变量中的数据类型,在使用 typeof 运算符时,有几个注意事项需要注意:

  1. typeof null 返回 "object": 这是一个历史遗留问题,typeof null 返回 "object",而不是 "null"。这是因为在 JavaScript 的早期版本中,将 null 值的类型标识为对象类型,但实际上 null 是一个原始值,表示一个空对象指针。因此,当使用 typeof 操作符检查 null 时,需要额外注意。
  2. typeof 无法区分数组和对象: 当使用 typeof 操作符检查数组时,返回的结果是 "object",而不是 "array"。这是因为在 JavaScript 中,数组是对象的一种特殊形式。如果需要判断一个值是否为数组,可以使用 Array.isArray() 方法来进行准确的判断。
  3. typeof 对于函数返回 "function": 当使用 typeof 操作符检查函数时,返回的结果是 "function"。这可以用来区分函数和其他类型的值。
  4. typeof 对于未声明的变量返回 "undefined": 当使用 typeof 操作符检查未声明的变量时,返回的结果是 "undefined"。这可以用来检查变量是否已经声明。
  5. typeof 返回的都是字符串: typeof 操作符返回的结果都是字符串,即使操作数是一个对象、函数或其他类型的值。这是因为 typeof 是一个一元运算符,总是返回一个字符串值。

判断数据类型总结:

基本类型使用typeof即可,对于对象数组和函数,使用Object.prototype.toString.call()

  1. Object.prototype.toString.call([])=====>[object Array]
  2. Object.prototype.toString.call({})=====>[object Object]
  3. Object.prototype.toString.call(()=>{})====>[object Function]

运算符运算元

运算元,一元运算符,二元运算符的定义

运算符作用的对象叫做运算元,比如表达式5 * 2,该表达式就有两个运算元,5跟2,如果一个运算符对应的只有一个运算元,那么它是 一元运算符。比如说一元负号运算符-;如果一个运算符拥有两个运算元,那么它是 二元运算符。减号还存在二元运算符形式

let a = 1;
a = -a; //一元运算符
console.log(a) //-1
    
let x = 1, y = 2;
console.log(x - y) //二元运算符

运算符优先级

关于运算符的优先级,记住一句话:一元运算符先于二元运算符作用于运算元,赋值运算符优先级非常低,在 JavaScript 中,所有运算符都会返回一个值。这对于加减乘除来说是显而易见的,但对于 = 来说也是如此,比如语句x = value将值 value 写入 x 然后返回 value

let a = 1;  
let b = 2;   
let c = 3 - (a = b + 1);

自增自减

分为前置自增自减++count和后置自增自减count++,两者区别就在于返回值,所有运算符都有返回值,前置返回值是返回最新的,而后置是返回原来的值

let counter = 1;  
let a = ++counter; 
alert(a); // 2
let counter = 1;  
let a = counter++; 
alert(a); // 1

自增自减优先级比绝大部分的算数运算符优先级要高

let a = 1;
let b = 1;
alert(2 * ++a); //4
alert(2 * a++); //2

总结:如果自增/自减的值不会被使用,那么两者形式没有区别,如果我们想要对变量进行自增操作,并且需要立刻使用自增后的值,那么我们需要使用前置,如果我们想要将一个数加一,但是我们想使用其自增之前的值,那么我们需要使用后置

逗号元算符

逗号运算符能让我们处理多个表达式,每个表达式都运行了,但是只有最后一个的结果会被返回

let a = (1+2,3+4);
alert(a); //7

类型转换与运算符易错

"4px" - 2 = NaN
//减法运算符需要数字类型的运算元,所以会将"4px"转换为数字,由于字符串中包含非数字字符"px",无法将其转换为有效的数字,所以结果为NaN,NaN转为数字为NaN,NaN-2=NaN
" -9 " - 5 = -14
//字符串转为数字时会忽略首尾空格
" \t \n" - 2 = -2
//在表达式 " \t \n" - 2 中,字符串 " \t \n" 包含了空格、制表符和换行符。这些字符在转换为数字时会被忽略,所以该表达式被解释为0,0-2=-2
null + 1 = 1undefined + 1 = NaN
//null 经过数字转换之后会变为 0,undefined 经过数字转换之后会变为 NaN

值的比较

  1. 在比较字符串的大小时,JavaScript 会使用字典或词典顺序进行判定,所以字符串是按字符(母)逐个进行比较的,比如"2" > "12"为true,因为首位字符 "2" 大于 "1""apple" > "pineapple"为false,因为"a" 比 "p" 小
  2. undefined 和 null 在相等性检查 == 中不会进行任何的类型转换,它们有自己独立的比较规则,所以除了它们之间互等外,不会等于任何其他的值,比如undefined == null为true,null == 0为false,都知道null转为数字为0,但null除了与自身和undefined,不会等于其他值
  3. NaN 是一个特殊的数值型值,它与任何值进行比较都会返回 false
  4. 在使用 > 或 < 进行比较时,需要注意变量可能为 null/undefined 的情况。比较好的方法是单独检查变量是否等于 null/undefined

空值合并运算符??

空值运算符是获取两者中第一个已定义的值

a ?? b结果: 如果a是已定义的,则结果为a; 如果a不是已定义的,则结果为b

??与||的区别

||返回第一个真值,??返回第一个已定义的值,即||无法区分false,0,空串和null/undefined,他们都是假值,但在实际中,可能只想在null或者undefined时(即当该值未知或者未被设置时)使用默认值

注意:js禁止??和&&、||一起使用,除非使用了括号明确指定了优先级

循环

while循环,当condition为真时执行循环体

while(condition){
    循环体
}

do..while循环

do{
    循环体
}while(condition)

先执行循环体,然后检查condition,为真时再接着执行循环体 for循环

for(begin;condition;step){
    循环体body
}

示例:

for(let i = 0; i < 3; i++){
    alert(i);
}
语句段
beginlet i = 0进入循环时执行一次
conditioni < 3在每次循环迭代之前检查,如果为 false,停止循环。
bodyalert(i)条件为真时,重复运行。
stepi++在每次循环体迭代后执行。

break/continue

js允许我们通过break跳出整个循环,breakcontinue的区别在于,continue不会停掉整个循环,而是停止当前这次的迭代,并强制启动下一轮的循环

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

上述代码当i为偶数时跳出了整个循环,所以只打印了11

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

换成continue,当i为偶数时跳出了本次循环并启动了下一轮循环,所以打印了11,13

如何跳出多层嵌套的循环?

有时我们需要从多层嵌套的循环中跳出来,这需要借助标签来实现这一功能

标签语法:

labelName: for(...) {...}

break <labelName> 语句跳出循环至标签处,看下面代码:

for(let i = 1; i<=2;i++){  
    console.log('outer')  
    for(let j = 20;j<22;j++){  
        if(j%2 != 0) break;  
        console.log(i+j)  
    }  
}  

比如该段循环,当j为偶数时才输出,奇数时跳出里层循环,外层循环还继续着,所以打印了outer、21、outer、22

outer:for(let i = 1; i<=2;i++){  
    console.log('outer')  
    for(let j = 20;j<22;j++){  
        if(j%2 != 0) break outer;  
        console.log(i+j)  
    }  
}

加上标签,这样当j为奇数时,就会跳出最外层循环,所以打印结果为,outer、21

注意:非表达式的语法结构不能与三元运算符 ? 一起使用,所以禁止break/continue 在 ‘?’ 的右边,比如(i > 5) ? alert(i) : continue;是不被允许的

break/continue 支持循环前的标签。标签是 break/continue 跳出嵌套循环以转到外部的唯一方法

转载自:https://juejin.cn/post/7275532902942244899
评论
请登录