当前位置: 首页 > news >正文

V少JS基础班之第四弹

一、 前言

第四弹内容是操作符。 本章结束。第一个月的内容就完成了, 是一个节点。 下个月我们就要开始函数的学习了。 我们学习完函数之后。很多概念就可以跟大家补充说明了。 OK,那我们就开始本周的操作符学习
本系列为一周一更,计划历时6个月左右。从JS最基础【变量与作用域】到【异步编程,密码学与混淆】。希望自己能坚持下来, 也希望给准备入行JS逆向的朋友一些帮助, 第一次要点赞,评论和收藏。也是希望如果本专栏真的对大家有帮助可以点个赞,有建议或者疑惑可以在下方随时问。
先预告一下【V少JS基础班】的全部内容。看着很少,其实,正儿八经细分下来其实挺多的,第一个月的东西也一点不少。
第一个月【变量作用域BOMDOM数据类型操作符
第二个月【函数、闭包、原型链、this】
第三个月【面向对象编程、异步编程、nodejs】
第四个月【密码学、各类加密函数】
第五个月【jsdom、vm2、express】
第六个月【基本请求库、前端知识对接】

二、本节涉及知识点

 操作符

三、重点内容

1- 初始操作符:

在 JavaScript 中,操作符(Operators) 是用来执行各种操作的符号或关键字。操作符可以操作数据(如变量、值)并产生结果。根据操作的对象类型和操作的方式,JavaScript 的操作符可以分为不同的种类。
口语OS: 我们看到的js代码, 无外乎: 常量、变量(声明&赋值)、各种数据类型、操作符、函数、对象、数组、事件、控制流、错误处理、异步编程、模块化等。我们把每个点都过一遍。再复杂的js代码也没有什么看不懂的。

2- 操作符的分类:

操作符是用来操作数据或变量的符号。JavaScript 中的操作符可以分为以下几类:

算术操作符:+、-、*、/、%、++、--
赋值操作符:=、+=、-=、*=、/=、%= 等
比较操作符:==、===、!=、!==、<、>、<=、>=
逻辑操作符:&&、||、!
位操作符:&、|、^、<<、>>、>>>
三元操作符:condition ? expr1 : expr2
类型操作符:typeof、instanceof、in
成员操作符:.、[](访问对象属性或数组元素)
1. 算术操作符

这些操作符用于执行基本的数学运算,如加法、减法、乘法等。

+(加法): 加法运算符,用于两个数相加,或者连接字符串。

5 + 3 // 8
'Hello' + ' ' + 'World' // 'Hello World'

-(减法): 减法运算符,用于两个数相减。

5 - 3 // 2

*(乘法): 乘法运算符,用于两个数相乘。

5 * 3 // 15

/(除法): 除法运算符,用于两个数相除。

6 / 3 // 2

%(取余): 取余运算符,返回除法运算后的余数。

5 % 3 // 2

** (指数): 指数运算符,返回第一个数的指数次方。

2 ** 3 // 8

ok, 首先我们要明确一点。 计算操作符在计算之前,会优先将两边的变量隐式转换为数字类型。 除了一个例外。 那就是加法(+). 我们经常会看到以下代码:
在这里插入图片描述
为什么呢? 字符串1与1相加。返回的是字符串’11’。 而字符串1与1相减。就变成了0

OS:认真看
以上问题,就是我们在算数运算符中要注意的点。最基本的已经说过了,但凡碰到运算符。我们默认会将两边的数据转成数字类型。 那加法除外。加法有一套自己的优先级。那就是我们常说的隐式转换。 那我们现在来看一看隐式转换。

2. 隐式转换(Implicit Conversion)

隐式转换是在进行表达式运算时,编程语言会自动地将不同数据类型的值转换为兼容的类型,以避免运行时错误。加法操作符(+)在遇到不同类型的运算对象时,会涉及隐式类型转换。

加法隐式转换的优先级:
1- 如果加法操作数中有一个是字符串类型,那么另外一个操作数会被隐式转换为字符串,并且会执行字符串拼接操作。

let result = 10 + '5';  // '105'
这里,10 会被转换为字符串 '10',然后执行拼接,最终结果为 '105'

2- 数字与其他类型的加法:
如果加法操作数都是数字类型或可以转换为数字(例如字符串),JavaScript 会自动将其转换为数字进行加法运算。

let result = 10 + '5';  // '105'
let result2 = 10 + 5;   // 15
这里的情况涉及到字符串与数字的相加,如果有字符串参与,加法就会优先执行字符串拼接。

3- 布尔值与数字的加法:
布尔值 true 和 false 会分别转换为数字 1 和 0。比如:

let result = true + 1;  // 2
let result2 = false + 1; // 1

4- 对象与加法:
当其中一个操作数是对象时,会尝试调用对象的 toString()valueOf() 方法,将其转换为原始类型,然后再进行加法运算。如果这些方法无法进行转换,通常会返回 NaN(Not a Number)。

总结:
加法隐式转换的优先级 是字符串拼接优先于数字加法,布尔值会转换成数字,
某些复杂类型(如对象)会调用其 toString() 或 valueOf() 方法进行转换。
上节也有说过,对象的显示转换和隐式转换的优先级
2. 赋值操作符

1- 基本赋值操作符:
最常用的赋值操作符是 =,它用于将右侧的值赋给左侧的变量。

let x = 5;  // 将 5 赋值给变量 x
在上面的例子中,x 被赋值为 5

这里我们要说一下。 赋值语

2- 扩展赋值操作符
JavaScript 提供了一些扩展赋值操作符,可以简化对变量进行修改的过程。这些操作符会对变量进行某种运算后再赋值。
2.1 加法赋值操作符:+=

let x = 5;
x += 3;  // 等同于 x = x + 3;
console.log(x);  // 8

2.2 减法赋值操作符:-=

let x = 5;
x -= 2;  // 等同于 x = x - 2;
console.log(x);  // 3

2.3 乘法赋值操作符:*=

let x = 5;
x *= 2;  // 等同于 x = x * 2;
console.log(x);  // 10

2.4 除法赋值操作符:/=

let x = 10;
x /= 2;  // 等同于 x = x / 2;
console.log(x);  // 5

2.5 取余赋值操作符:%=

let x = 10;
x %= 3;  // 等同于 x = x % 3;
console.log(x);  // 1

2.6 幂赋值操作符:**=(ES6新增)

let x = 2;
x **= 3;  // 等同于 x = x ** 3;
console.log(x);  // 8

3.对象解构赋值:
在 ES6 中,JavaScript 引入了对象解构赋值,使得从对象中提取值并赋给变量变得更加简洁。

const obj = { a: 1, b: 2 };
const { a, b } = obj;  // 解构赋值
console.log(a);  // 1
console.log(b);  // 2
  1. 数组解构赋值:
const arr = [10, 20, 30];
const [x, y] = arr;  // 解构赋值
console.log(x);  // 10
console.log(y);  // 20

5.默认赋值:
解构赋值时,如果变量未被赋值,可以使用默认值。

const { a = 1, b = 2 } = { a: 5 };
console.log(a);  // 5
console.log(b);  // 2

6.条件赋值:||= 和 &&=(ES11新增)
6.1 逻辑或赋值操作符:||=
如果左边的值为 falsy(假值),则给变量赋予右边的值。

let x = 0;
x ||= 5;  // 如果 x 是 falsy(0),则 x = 5
console.log(x);  // 5

6.2 逻辑与赋值操作符:&&=
如果左边的值为 truthy(真值),则给变量赋予右边的值。

let x = 10;
x &&= 5;  // 如果 x 是 truthy(10),则 x = 5
console.log(x);  // 5
总结
=:基本的赋值操作符。
+=, -=, *=, /=, %= 等:用于修改变量的值,并赋值回去。
解构赋值:简洁地从对象或数组中提取值。
默认赋值:解构时设置默认值。
||= 和 &&=:条件赋值操作符,用于根据条件修改变量值。
3. 比较操作符

比较操作符用于比较两个值,并返回一个布尔值(true 或 false)。它们通常用于条件判断、循环控制和逻辑表达式中。

1.相等操作符:== 和 ===
==(抽象相等操作符):比较两个值是否相等,会进行类型转换,如果两个值的类型不同,会尝试转换成相同类型后再比较。

===(严格相等操作符):比较两个值是否相等,不会进行类型转换,只有值和类型都相等时才返回 true。

let a = '5';
let b = 5;console.log(a == b);  // true  (类型转换后,'5' 转为 5)
console.log(a === b); // false (类型不同,字符串和数字不相等)

!=(抽象不等操作符):比较两个值是否不相等,会进行类型转换。
!==(严格不等操作符):比较两个值是否不相等,不会进行类型转换,只有值或类型不相等时才返回 true。

let a = '5';
let b = 5;console.log(a != b);  // false  (类型转换后,'5' 转为 5)
console.log(a !== b); // true  (类型不同,字符串和数字不相等)

3.大于与小于:> 和 <

>:检查左侧的值是否大于右侧的值,返回 true 或 false。
<:检查左侧的值是否小于右侧的值,返回 true 或 false。
let a = 5;
let b = 10;console.log(a > b);  // false
console.log(a < b);  // true

4.大于等于与小于等于: >= 和 <=

>=:检查左侧的值是否大于或等于右侧的值。
<=:检查左侧的值是否小于或等于右侧的值。
let a = 5;
let b = 5;console.log(a >= b);  // true
console.log(a <= b);  // true

5.NaN 的比较

NaN(Not a Number)是一个特殊的数值,它不等于任何值,包括它自己。
也就是说,NaN == 	NaN 和 NaN === NaN 都返回 false。
let a = NaN;
let b = NaN;console.log(a == b);  // false
console.log(a === b); // false

要检查一个值是否是 NaN,可以使用 Number.isNaN() 方法:

console.log(Number.isNaN(a));  // true

6.字符串比较

在 JavaScript 中,字符串是基于字符的 Unicode 值进行比较的。
这意味着字符串的比较是逐个字符比较 Unicode 值的大小。
let a = 'apple';
let b = 'banana';console.log(a > b);  // false (根据字母顺序比较,第一个字符 'a' 比 'b' 小)
console.log(a < b);  // true

7.对象比较

在 JavaScript 中,对象比较是基于引用的,即比较两个对象是否指向同一个内存地址。
let obj1 = { name: 'Alice' };
let obj2 = { name: 'Alice' };
let obj3 = obj1;console.log(obj1 == obj2);  // false (虽然属性值相同,但它们是不同的对象)
console.log(obj1 === obj2); // false (对象比较是基于引用的)
console.log(obj1 === obj3); // true (obj3 和 obj1 引用的是同一个对象)
总结:
== 和 === 用于判断两个值是否相等,后者严格比较类型。
!= 和 !== 用于判断两个值是否不相等,后者严格比较类型。
>、<、>= 和 <= 用于比较数值的大小关系。
NaN 是一个特殊的数值,它不等于任何值,包括它自己。
字符串的比较是根据字符的 Unicode 值进行的。
对象的比较是基于引用的,即比较两个对象是否指向相同的内存地址。

OS: 口语化表达。 == 与=== 的区别在于一个会进行数据类型转换,一个不会。

4. 逻辑操作符

逻辑操作符用于布尔值的运算,常用于控制流语句(如 if、while 等),帮助我们处理逻辑判断。

1.与操作符:&&

&&(与操作符)用于检查两个表达式是否都为真,只有两个表达式都为 true 时,
结果才为 true,否则为 false。
let a = true;
let b = false;console.log(a && b);  // false (因为 b 为 false)
console.log(true && true);  // true
console.log(false && false);  // false

逻辑与运算的短路特性:

短路:当第一个表达式为 false 时,第二个表达式不会被计算,因为结果已经确定为 false。
console.log(false && (1 / 0));  // false (1 / 0 不会被执行)

2.或操作符:||

||(或操作符)用于检查两个表达式是否至少有一个为真,只有两个表达式都为 false 时,
结果才为 false,否则为 true。
let a = true;
let b = false;console.log(a || b);  // true (因为 a 为 true)
console.log(false || false);  // false

逻辑或运算的短路特性:

短路:当第一个表达式为 true 时,第二个表达式不会被计算,因为结果已经确定为 true。
console.log(true || (1 / 0));  // true (1 / 0 不会被执行)

3.非操作符:!

!(非操作符)用于对一个布尔值进行取反,即 true 变成 false,false 变成 true。
let a = true;
let b = false;console.log(!a);  // false (取反)
console.log(!b);  // true

4.逻辑运算中的“短路行为”

逻辑运算符 && 和 || 都具有短路特性,它们会在运算过程中提前结束,减少不必要的运算。
&& 短路:如果第一个操作数为 false,则第二个操作数不会被求值,因为不管第二个操作数是什么,
结果都必然为 false。
|| 短路:如果第一个操作数为 true,则第二个操作数不会被求值,因为不管第二个操作数是什么,
结果都必然为 true。

5.逻辑运算符的其他用法

JavaScript 中的逻辑运算符不仅用于布尔值之间的逻辑判断,还常常用于 条件判断 或 赋值操作。

5.1 逻辑与 (&&) 与条件表达式

在 JavaScript 中,逻辑与运算符(&&)常用于简化条件表达式,返回第一个为 false 的值,或者返回最后一个值。
let a = 5;
let b = 10;let result = (a > b) && 'True';  // 'True'(因为 a > b 是 false,结果是 false)
console.log(result); // falselet result2 = (a < b) && 'True'; // 'True'(因为 a < b 是 true,结果是 'True')
console.log(result2); // 'True'

5.2 逻辑或 (||) 与条件表达式

逻辑或运算符(||)常用于返回第一个为 true 的值,或者返回最后一个值。
let a = 0;
let b = 10;let result = (a || b);  // 10 (因为 a 是 falsy 值,返回 b)
console.log(result); // 10

6.布尔值的隐式转换

逻辑操作符也会涉及到布尔值的隐式类型转换。JavaScript 中的 假值(falsy values) 会在逻辑运算中被自动转换为 false,而 真值(truthy values) 会被自动转换为 true。
假值(falsy values):
false、0、""(空字符串)、null、undefined、NaN
真值(truthy values):
除了上述的假值,其他所有值都是 truthy 值,包括非空字符串、非零数字、对象、数组等。
console.log(0 || 'hello');   // 'hello' (0 是 falsy,返回 'hello')
console.log('' || 'world');  // 'world' (空字符串是 falsy,返回 'world')
console.log(true && 'yes');  // 'yes' (true 是 truthy,返回 'yes')
console.log(false && 'no');  // false (false 是 falsy,返回 false)

7.综合使用

在条件判断中,逻辑运算符的组合使用非常常见,可以在一行中进行复杂的逻辑判断。
let age = 25;
let hasPermission = true;if (age >= 18 && hasPermission) {console.log('Access granted');
} else {console.log('Access denied');
}let username = '';
let defaultUsername = 'Guest';let result = username || defaultUsername; // 'Guest' (因为 username 是 falsy,返回 defaultUsername)
console.log(result);  // 'Guest'
总结:
&&:返回两个表达式的 true 值,只有当两个操作数都为 true 时,结果为 true。具有短路行为。
||:返回两个表达式的 true 值,只要有一个操作数为 true,结果就是 true。也具有短路行为。
!:将布尔值取反。
短路行为:逻辑操作符的短路特性可以帮助优化代码执行。
布尔值的隐式转换:JavaScript 中的假值和真值会自动转换为 false 或 true,可以方便地进行逻辑判断。
5. 位操作符

位操作符在 JavaScript 中主要用于对整数的二进制位进行操作。它们直接对数字的二进制表示进行操作,这些操作是基于二进制位的 逻辑运算。

1.按位与操作符:&

& 操作符对两个操作数的每一位进行按位与运算。如果两个对应的二进制位都为 1,则结果为 1,否则为 0。
let a = 5;  // 二进制: 0101
let b = 3;  // 二进制: 0011
console.log(a & b);  // 1(二进制: 0001)
解释:
0101500113)
按位与运算的结果是:00011

2.按位或操作符:|

| 操作符对两个操作数的每一位进行按位或运算。如果两个对应的二进制位中至少有一个为 1,则结果为 1,否则为 0。
let a = 5;  // 二进制: 0101
let b = 3;  // 二进制: 0011
console.log(a | b);  // 7(二进制: 0111)
解释:
0101500113)
按位或运算的结果是:01117

3.按位异或操作符:^

^ 操作符对两个操作数的每一位进行按位异或运算。当两个二进制位不同(一个为 0,另一个为 1)时,结果为 1;
当两个二进制位相同(两个都为 0 或两个都为 1)时,结果为 0。
let a = 5;  // 二进制: 0101
let b = 3;  // 二进制: 0011
console.log(a ^ b);  // 6(二进制: 0110)
解释:
0101500113)
按位异或运算的结果是:01106

4.按位非操作符: ~

~ 操作符对操作数的每一位进行按位非运算,也就是将每一位 0 变成 1,将每一位 1 变成 0。
let a = 5;  // 二进制: 0101
console.log(~a);  // -6(二进制: 1010)
解释:
01015)
按位非运算后的结果是:1010-6
注意: 按位非操作符执行的是 取反,但它与普通的数学取反不同,
因为 JavaScript 中的数字是 32 位有符号整数,结果会受到 二进制补码 的影响。

5.左移操作符:<<

<< 操作符将数字的二进制位向左移动指定的位数。每左移一位,相当于将数字乘以 2。
let a = 5;  // 二进制: 0101
console.log(a << 1);  // 10(二进制: 1010)
console.log(a << 2);  // 20(二进制: 10100)
解释:
01015)左移 1 位后,变成 10101001015)左移 2 位后,变成 1010020

6.带符号右移操作符:>>

>> 操作符将数字的二进制位向右移动指定的位数。对于带符号整数,它会保持符号位(即负数会保持负号)。
每右移一位,相当于将数字除以 2。
let a = 5;   // 二进制: 0101
let b = -5;  // 二进制: 11111111111111111111111111111011(32 位)
console.log(a >> 1);  // 2(二进制: 0010)
console.log(b >> 1);  // -3(二进制: 11111111111111111111111111111101)
解释:
01015)右移 1 位后,变成 0010211111111111111111111111111111011-5)右移 1 位后,变成 11111111111111111111111111111101-3

7.无符号右移操作符:>>>

>>> 操作符将数字的二进制位向右移动指定的位数,但不同于 >>,它 不保持符号位,
即使是负数也会将符号位当作普通位来处理。
let a = 5;   // 二进制: 0101
let b = -5;  // 二进制: 11111111111111111111111111111011(32 位)
console.log(a >>> 1);  // 2(二进制: 0010)
console.log(b >>> 1);  // 2147483643(二进制: 01111111111111111111111111111111)
解释:
01015)无符号右移 1 位后,变成 0010211111111111111111111111111111011-5)无符号右移 1 位后,变成 011111111111111111111111111111112147483643
总结:
按位与 &:两个二进制位都为 1 时,结果为 1。
按位或 |:只要一个二进制位为 1,结果为 1。
按位异或 ^:两个二进制位不同,结果为 1,相同则为 0。
按位非 ~:将每一位取反(0 变 1,1 变 0)。
左移 <<:将二进制位向左移动,类似于乘以 2。
带符号右移 >>:将二进制位向右移动,保持符号位。
无符号右移 >>>:将二进制位向右移动,不保持符号位。
6. 三元操作符
三元操作符是一种 简化的条件表达式,它可以用来代替常规的 if-else 语句。
三元操作符有三个部分,所以叫做三元(ternary)操作符。condition ? expression_if_true : expression_if_false;
condition:这是一个布尔表达式。它的值可以是 true 或 false。
expression_if_true:如果 condition 为 true,则返回这个表达式的值。
expression_if_false:如果 condition 为 false,则返回这个表达式的值。
let age = 18;
let canVote = (age >= 18) ? "Yes, you can vote!" : "No, you're too young.";
console.log(canVote);  // 输出:Yes, you can vote!
解释:
age >= 18 是条件表达式,它会被评估为 true(因为 age 等于 18)。
如果条件为 true,就返回 "Yes, you can vote!"。
如果条件为 false,就返回 "No, you're too young."
let score = 85;
let grade = (score >= 90) ? "A" : (score >= 80) ? "B" : (score >= 70) ? "C" : "F";
console.log(grade);  // 输出:B解释:
首先,检查 score >= 90,如果为 true,返回 "A"。
如果 score >= 90false,接着检查 score >= 80,如果为 true,返回 "B"。
如果两个条件都为 false,继续检查 score >= 70,如果为 true,返回 "C"。
如果所有条件都为 false,返回 "F"
function checkAccess(age) {return (age >= 18) ? "Access granted" : "Access denied";
}console.log(checkAccess(20));  // 输出:Access granted
console.log(checkAccess(16));  // 输出:Access denied
解释:
根据 age 的值,三元操作符决定返回 "Access granted" 还是 "Access denied"。
优点:
简洁性:三元操作符将 if-else 语句简化为一行代码,适合用于简单的条件判断。
可读性:对于短小的条件判断,三元操作符使代码更加简洁,容易理解。
缺点:
过度嵌套:如果将多个三元操作符嵌套使用,可能会导致代码难以理解,降低可读性。
不适用于复杂的逻辑:对于复杂的条件判断,还是推荐使用 if-else 语句,因为它会更加清晰。
总结:
三元操作符是条件表达式的简化形式,使用起来简洁高效,适用于简短的条件判断。
它有三个部分:条件、条件为 true 时的结果、条件为 false 时的结果。
尽管三元操作符可以嵌套使用,但如果条件逻辑复杂,使用传统的 if-else 语句可能更为合适。
let userInput = null;
let name = userInput ? userInput : "Guest";
console.log(name);  // 输出:Guest解释:
userInput 是 null,所以条件表达式 userInput 为 false。
因此,返回 "Guest",并且 name 的值为 "Guest"
7. 类型操作符

1.typeof 操作符

前面已经讲过 typeof,它是一个非常常见的操作符,用于获取变量的数据类型。接下来,
我们可以再详细地讨论一下 typeof 在不同情况下的返回值。
typeof operand
operand:表示要检查的值(变量或表达式)。
特殊情况:
typeof null:返回 "object",这是 JavaScript 中的一个历史遗留问题。虽然 null 是原始类型(primitive type),但 typeof null 却返回 "object",这一点需要特别注意。
console.log(typeof null);  // 输出:object
typeof 对数组的返回值:数组是对象的一种特殊形式,typeof 对数组的判断返回 "object",所以如果要判断一个变量是否为数组,需要使用 Array.isArray() 方法。
let arr = [1, 2, 3];
console.log(typeof arr);  // 输出:object
typeof 对函数的返回值:对于函数,typeof 会返回 "function"
function foo() {}
console.log(typeof foo);  // 输出:function

2.instanceof 操作符

instanceof 用于判断一个对象是否为某个构造函数的实例。这个操作符常常用于类的实例化检测。
object instanceof constructor
object:要检查的对象。
constructor:构造函数或类,通常是对象的类型。
let arr = [1, 2, 3];
console.log(arr instanceof Array);  // 输出:truelet date = new Date();
console.log(date instanceof Date);  // 输出:truelet num = 10;
console.log(num instanceof Number);  // 输出:false(因为 num 不是通过 Number 构造函数创建的)let obj = {};
console.log(obj instanceof Object);  // 输出:true
注意:
instanceof 检查的是对象的原型链,能有效地检测对象是否是某个类的实例或继承自某个类的实例。
它不能用于基本数据类型,比如 number、string、boolean 等。

3.constructor 属性

constructor 是每个对象都有的属性,指向该对象的构造函数。通过 constructor 属性,你可以检查对象的类型。
let arr = [1, 2, 3];
console.log(arr.constructor === Array);  // 输出:truelet date = new Date();
console.log(date.constructor === Date);  // 输出:truelet obj = {};
console.log(obj.constructor === Object);  // 输出:true
注意:
constructor 只适用于对象,对于原始类型如数字和字符串,它并不存在。

4.Array.isArray() 方法

Array.isArray() 是专门用来判断一个值是否是数组的静态方法。typeof 无法区分数组和普通对象,
所以使用 Array.isArray() 来准确检查数组是一个好选择。
Array.isArray(value)
value:要检查的值。
示例:
javascript
复制代码
let arr = [1, 2, 3];
console.log(Array.isArray(arr));  // 输出:truelet obj = {};
console.log(Array.isArray(obj));  // 输出:false

5.new 操作符

new 操作符用来创建实例化对象。它与构造函数一起使用,可以创建特定类型的对象实例。
function Person(name) {this.name = name;
}let person1 = new Person("Alice");
console.log(person1 instanceof Person);  // 输出:true
注意:
new 操作符会调用构造函数并返回实例对象。

6.Object() 操作符

Object() 是 JavaScript 中的一个内置函数,用来将一个值转换成对象类型。特别是对于原始类型,
Object() 会将它们包装成对象。
let str = "hello";
let objStr = Object(str);
console.log(typeof objStr);  // 输出:objectlet num = 123;
let objNum = Object(num);
console.log(typeof objNum);  // 输出:object
注意:
Object() 会将原始值(例如字符串、数字、布尔值)转换为它们的包装对象(String、Number、Boolean)。

7.toString() 方法

每个对象都继承自 Object,并且有一个 toString() 方法。这个方法会返回对象的字符串表示形式,
通常用于将对象转换成字符串。
let obj = { name: "Alice" };
console.log(obj.toString());  // 输出:"[object Object]"let arr = [1, 2, 3];
console.log(arr.toString());  // 输出:"1,2,3"
注意:
对象的 toString() 方法默认返回 [object Object],但你可以在自定义类中重写这个方法。
总结:
typeof:检测基本数据类型,注意 null 会返回 "object",数组和函数有特殊的返回值。
instanceof:检查一个对象是否是某个构造函数或类的实例。
constructor:对象的属性,返回对象的构造函数,适用于对象类型。
Array.isArray():专门判断一个值是否为数组。
new:用于实例化对象。
Object():将原始值转换为对象。
toString():将对象转换为字符串。
8. 成员操作符
成员操作符(Member Operators)主要用于访问对象或数组的属性或元素。它们是操作对象和数组的关键工具,
常见的有 点操作符(.)和 方括号操作符([])。这两种操作符用于访问对象的属性或数组的元素,
但它们在使用时有不同的语法规则和特点。

1.点操作符(.)

点操作符是 JavaScript 中最常用的成员操作符之一,它用于访问对象的属性或方法。
使用点操作符时,属性名称必须是有效的标识符(例如,不可以包含空格或特殊字符)。
object.property
object:目标对象。
property:要访问的属性名称,必须是有效的标识符。
示例:
javascript
复制代码
let person = {name: "Alice",age: 25,greet: function() {console.log("Hello, " + this.name);}
};console.log(person.name);  // 输出:"Alice"
console.log(person.age);   // 输出:25
person.greet();  // 输出:"Hello, Alice"
注意:
使用点操作符时,属性名称必须是有效的标识符。
如果属性名称包含空格或特殊字符,不能使用点操作符(例如:person["first name"]),这时应使用方括号操作符。

2.方括号操作符([])

方括号操作符用于访问对象的属性或数组的元素。它比点操作符更灵活,允许使用动态或变量作为属性名称,
并支持字符串中包含空格或特殊字符的属性名。

3.成员访问(in 操作符)

property in object
property:要检查的属性名称。
object:要检查的对象。
示例:
javascript
复制代码
let person = {name: "Alice",age: 25
};console.log("name" in person);  // 输出:true
console.log("gender" in person);  // 输出:false
注意:
in 操作符会检查对象及其原型链中是否有指定的属性。

4.成员遍历(for…in 循环)

for...in 循环用于遍历对象的所有可枚举属性,包括继承的属性。它可以用来访问对象的所有成员。
for (let key in object) {// 执行操作
}
key:属性名称的变量。
object:要遍历的对象。let person = {name: "Alice",age: 25
};for (let key in person) {console.log(key + ": " + person[key]);
}
// 输出:
// name: Alice
// age: 25
注意:
for...in 遍历的是对象的可枚举属性,包括继承的属性。如果只想遍历对象本身的属性,可以结合 hasOwnProperty() 方法使用。

5.数组下标操作符([])

对于数组,方括号操作符不仅可以用来访问数组元素,还可以用来设置数组元素的值。
let arr = [1, 2, 3];
arr[0] = 100;  // 修改第一个元素
console.log(arr[0]);  // 输出:100

6.对象解构赋值(Destructuring)

虽然解构赋值不是传统意义上的“成员操作符”,但它允许通过属性名从对象或数组中提取值。
这是 JavaScript ES6 引入的一个语法糖。
let person = {name: "Alice",age: 25
};let { name, age } = person;
console.log(name);  // 输出:"Alice"
console.log(age);   // 输出:25let arr = [1, 2, 3];
let [first, second] = arr;
console.log(first);  // 输出:1
console.log(second); // 输出:2
总结:
.(点操作符):用于访问对象的属性或方法,适用于有效标识符的属性名称。
[](方括号操作符):可以动态访问对象的属性或数组的元素,支持使用变量或包含空格、特殊字符的属性名。
in 操作符:用于检查对象中是否存在某个属性。
for...in 循环:遍历对象的可枚举属性。
数组下标操作符:用于访问或修改数组的元素。
对象解构赋值:通过解构语法从对象或数组中提取值。

操作符是JavaScript的基础之一。 也是js逆向中必定包含的知识点。 所以每个操作符都需要理解。 其中包括经典的。 a++ 和 ++a的区别等。

相关文章:

V少JS基础班之第四弹

一、 前言 第四弹内容是操作符。 本章结束。第一个月的内容就完成了&#xff0c; 是一个节点。 下个月我们就要开始函数的学习了。 我们学习完函数之后。很多概念就可以跟大家补充说明了。 OK&#xff0c;那我们就开始本周的操作符学习 本系列为一周一更&#xff0c;计划历时6…...

从前端视角看设计模式之创建型模式篇

设计模式简介 "设计模式"源于GOF&#xff08;四人帮&#xff09;合著出版的《设计模式&#xff1a;可复用的面向对象软件元素》&#xff0c;该书第一次完整科普了软件开发中设计模式的概念&#xff0c;他们提出的设计模式主要是基于以下的面向对象设计原则&#xff…...

网络应用技术 实验七:实现无线局域网

一、实验简介 在 eNSP 中构建无线局域网&#xff0c;并实现全网移动终端互相通信。 二、实验目的 1 、理解无线局域网的工作原理&#xff1b; 2 、熟悉无线局域网的规划与构建过程&#xff1b; 3 、掌握无线局域网的配置方法&#xff1b; 三、实验学时 2 学时 四、实…...

Kotlin 循环语句详解

文章目录 循环类别for-in 循环区间整数区间示例1&#xff1a;正向遍历示例2&#xff1a;反向遍历 示例1&#xff1a;遍历数组示例2&#xff1a;遍历区间示例3&#xff1a;遍历字符串示例4&#xff1a;带索引遍历 while 循环示例&#xff1a;计算阶乘 do-while 循环示例&#xf…...

B+树的原理及实现

文章目录 B树的原理及实现一、引言二、B树的特性1、结构特点2、节点类型3、阶数 三、B树的Java实现1、节点实现2、B树操作2.1、搜索2.2、插入2.3、删除2.4、遍历 3、B树的Java实现示例 四、总结 B树的原理及实现 一、引言 B树是一种基于B树的树形数据结构&#xff0c;它在数据…...

ArkTS 基础语法:声明式 UI 描述与自定义组件

1. ArkTS 简介 ArkTS 是 HarmonyOS 应用开发中的一种编程语言&#xff0c;它结合了 TypeScript 的类型检查和声明式 UI 描述方式&#xff0c;帮助开发者更高效地构建用户界面。 2. 声明式 UI 描述 ArkTS 使用声明式语法来定义 UI 结构&#xff0c;通过组件、属性和事件配置实…...

list的模拟实现详解

文章目录 list的模拟实现list的迭代器begin()和end() list的模拟实现 #pragma once #include<iostream> #include<list>using namespace std;namespace wbc {// 类模版template<class T>struct list_node // 链表的节点{T _data;list_node<T>* _next;…...

图解Git——分支的新建与合并《Pro Git》

⭐分支的新建与合并 先引入一个实际开发的工作流&#xff1a; 开发某个网站。为实现某个新的需求&#xff0c;创建一个分支。在这个分支上开展工作。 正在此时&#xff0c;你突然接到一个电话说有个很严重的问题需要紧急修补。你将按照如下方式来处理&#xff1a; 切换到你…...

SQLite 语法快速入门

SQLite 是一个软件库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。 提供一个免费的在线SQLite编辑器 &#xff08;0&#xff09;常用命令 # 格式化 .header on .mode column .timer on# 查看表格 .tables# 查看表结构(建表语句) .schema …...

高速光电探测器设计 PIN APD铟镓砷TIA放大脉冲误码测试800-1700nm

高速光电探测器PIN APD铟镓砷TIA放大脉冲误码测试800-1700nm &#xff08;对标:索雷博APD431A&#xff09; &#xff08;对标:索雷博APD431A&#xff09; &#xff08;对标:索雷博APD431A&#xff09; 规格参数: 波长范围:800-1700nm 输出带宽:DC-400MHz&#xff08;-3dB&…...

【Linux】【内存】Buddy内存分配基础 NUMA架构

【Linux】【内存】Buddy内存分配基础 NUMA架构 NUMA架构 在 NUMA 架构中&#xff0c;计算机的多个 CPU 被划分为不同的处理单元&#xff0c;每个处理单元有一个本地内存。这些内存被称为内存节点&#xff08;memory node&#xff09;。处理器尽量访问自己的本地内存 node_da…...

【机器学习:十九、反向传播】

1. 计算图和导数 计算图的概念 计算图&#xff08;Computation Graph&#xff09;是一种有向无环图&#xff0c;用于表示数学表达式中的计算过程。每个节点表示一个操作或变量&#xff0c;每条边表示操作的依赖关系。通过计算图&#xff0c;可以轻松理解和实现反向传播。 计算…...

使用中间件自动化部署java应用

为了实现你在 IntelliJ IDEA 中打包项目并通过工具推送到两个 Docker 服务器&#xff08;172.168.0.1 和 172.168.0.12&#xff09;&#xff0c;并在推送后自动或手动重启容器&#xff0c;我们可以按照以下步骤进行操作&#xff1a; 在 IntelliJ IDEA 中配置 Maven 或 Gradle 打…...

Vue.js开发入门:从零开始搭建你的第一个项目

前言 嘿&#xff0c;小伙伴们&#xff01;今天咱们来聊聊 Vue.js&#xff0c;一个超火的前端框架。如果你是编程小白&#xff0c;别怕&#xff0c;跟着我一步步来&#xff0c;保证你能轻松上手&#xff0c;搭建起属于自己的第一个 Vue 项目。Vue.js 可能听起来有点高大上&#…...

基于大语言模型的组合优化

摘要&#xff1a;组合优化&#xff08;Combinatorial Optimization, CO&#xff09;对于提高工程应用的效率和性能至关重要。随着问题规模的增大和依赖关系的复杂化&#xff0c;找到最优解变得极具挑战性。在处理现实世界的工程问题时&#xff0c;基于纯数学推理的算法存在局限…...

mySQL安装(LINUX)

一、1. 下载并安装MySQL官方的 Yum Repository 1、连接云服务器&#xff0c;进入opt 2、下载安装包 wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm 3、解压 rpm -ivh mysql-community-release-el7-5.noarch.rpm 4、安装 yum install mysql-commu…...

【机器学习】农业 4.0 背后的智慧引擎:机器学习助力精准农事决策

我的个人主页 我的领域&#xff1a;人工智能篇&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;&#x1f44d;点赞 收藏❤ 在当今数字化浪潮汹涌澎湃之际&#xff0c;农业领域正经历着一场前所未有的深刻变革&#xff0c;大踏步迈向农业 4.0时代。这一时代…...

在 Azure 100 学生订阅中新建一台 Ubuntu VPS,并通过 Docker 部署 Nginx 服务器

今天来和大家分享一下如何在 Azure 100 学生订阅中创建一台 Ubuntu VPS&#xff0c;并在其上通过 Docker 部署 Nginx 服务器。在这个过程中&#xff0c;我们将一步步走过每一个细节&#xff0c;希望能帮助到大家。 Docker 和 Nginx 简介 Docker 是一个开源的容器化平台&#…...

快速、可靠且高性价比的定制IP模式提升芯片设计公司竞争力

作者&#xff1a;Karthik Gopal&#xff0c;SmartDV Technologies亚洲区总经理 智权半导体科技&#xff08;厦门&#xff09;有限公司总经理 无论是在出货量巨大的消费电子市场&#xff0c;还是针对特定应用的细分芯片市场&#xff0c;差异化芯片设计带来的定制化需求也在芯片…...

Linux常用命令大全

mv详解目录 Linux 常用命令大全 1. ls 指令 2. touch 指令 3. pwd 指令 4. mkdir 指令 5. cd 指令 6. rmdir 和 rm 指令 7. man 指令 8. cp 指令 9. mv 指令 10. cat 指令 11. more 指令 12. less 指令 13. head 指令 14. tail 指令 15. find 指令 16. grep 指…...

K-均值聚类算法

K-均值聚类算法是一种常用的无监督学习算法&#xff0c;用于将数据集划分为K个不同的簇。它的基本思想是通过迭代将样本点划分到最相邻的簇中&#xff0c;以最小化各个簇内的平均距离。下面我们来详细讲解K-均值聚类算法的步骤及其优缺点。 步骤&#xff1a; 1. 随机选择K个质…...

Windows 环境下安装和启动 Redis 服务

在 Windows 环境下安装和启动 Redis 服务可以通过多种方式实现&#xff0c;下面将详细介绍几种常见的方法。我们将重点介绍通过 Chocolatey 包管理器、Docker 容器以及 MSOpenTech 提供的官方移植版来安装 Redis。 方法一&#xff1a;使用 Chocolatey 安装 Redis Chocolatey …...

关于在windows系统中编译ffmpeg并导入到自己项目中这件事

关于在windows系统中编译ffmpeg并导入到自己项目中这件事 前因&#xff08;可跳过不看&#xff09; 前阵子由于秋招需求&#xff0c;写了一个简易的安卓播放器&#xff0c;最终因为时间问题还有一些功能没有实现着实可惜&#xff0c;如&#xff1a;倍速播放&#xff0c;快进操…...

实战开发:基于用户反馈筛选与分析系统的实现

引言 在当今的数字化社会中&#xff0c;用户反馈是企业决策的重要依据。无论是电商平台、社交网络&#xff0c;还是产品服务&#xff0c;收集用户反馈并加以分析&#xff0c;有助于提升用户体验&#xff0c;改善服务质量。然而&#xff0c;面对海量的用户反馈&#xff0c;如何有…...

Android SystemUI——服务启动流程(二)

在 Andorid 系统源码中&#xff0c;package/apps下放的是系统内置的一些 APP&#xff0c;例如 Settings、Camera、Phone、Message 等等。而在 framework/base/package 下&#xff0c;它们也是系统的 APP&#xff0c;SystemUI 就在此目录下。它控制着整个 Android 系统的界面&am…...

拷贝构造函数

文章目录 一、4. 拷贝构造函数 今天我们来学习拷贝构造函数。 一、4. 拷贝构造函数 如果⼀个构造函数的第⼀个参数是自身类型的引用&#xff0c;且任何额外的参数都有默认值&#xff0c;则此叫做拷贝构造函数&#xff0c;也就是说拷贝构造是⼀个特殊的构造函数。 它的形式是这…...

解析OVN架构及其在OpenStack中的集成

引言 随着云计算技术的发展&#xff0c;虚拟化网络成为云平台不可或缺的一部分。为了更好地管理和控制虚拟网络&#xff0c;Open Virtual Network (OVN) 应运而生。作为Open vSwitch (OVS) 的扩展&#xff0c;OVN 提供了对虚拟网络抽象的支持&#xff0c;使得大规模部署和管理…...

面试加分项:Android Framework PMS 全面概述和知识要点

在Android面试时,懂得越多越深android framework的知识,越为自己加分。 目录 第一章:PMS 基础知识 1.1 PMS 定义与工作原理 1.2 PMS 的主要任务 1.3 PMS 与相关组件的交互 第二章:PMS 的核心功能 2.1 应用安装与卸载机制 2.2 应用更新与版本管理 2.3 组件管理 第…...

征服Windows版nginx(2)

1.配置Nginx 编辑Nginx的配置文件&#xff08;通常是nginx.conf&#xff09;&#xff0c;找到安装Nginx位置&#xff0c;如下路径&#xff1a; D:\nginx-1.26.2\conf 双击打开nginx.CONF编辑&#xff0c;在http块中添加一个新的server块&#xff0c;用于指定Vue项目的静态文件…...

QML states和transitions的使用

一、介绍 1、states Qml states是指在Qml中定义的一组状态&#xff08;States&#xff09;&#xff0c;用于管理UI元素的状态转换和属性变化。每个状态都包含一组属性值的集合&#xff0c;并且可以在不同的状态间进行切换。 通过定义不同的状态&#xff0c;可以在不同的应用场…...

flask_sqlalchemy relationship 子表排序

背景&#xff1a; 使用flask_sqlalchemy 的orm 时总不可避免的遇到子表排序问题 材料&#xff1a; 省略 制作&#xff1a; 直接看下面2段代码片段&#xff08;一对多关系组合&#xff09;&#xff0c;自行理解&#xff1a; 1、多的一方实体 from .exts import db from f…...

python+pymysql

python操作mysql 一、python操作数据库 1、下载pymysql 库&#xff0c; 方法一&#xff1a;pip3 install pymysql 或pip install pymysql 方法二&#xff1a;在pycharm中setting下载pymysql 2、打开虚拟机上的数据库 3、pymysql连接 dbpymysql.Connection(host&qu…...

HAL库 中断相关函数

目录 中断相关函数 函数&#xff1a;HAL_SuspendTick()和HAL_ResumeTick() 涉及手册&#xff1a; 涉及寄存器&#xff1a; 涉及位&#xff1a; 函数&#xff1a;HAL_UART_IRQHandler(&huart3) 存在位置&#xff1a; 拓展&#xff1a; 函数&#xff1a;HAL_UARTEx…...

薪资协商注意事项

根据从AI&#xff08;豆包kimi&#xff09;中查询的内容&#xff0c;以及实际面试中的经验&#xff0c;进行整理&#xff0c;供大家参考&#xff1a; 薪资构成&#xff1a;了解薪水的固定工资、绩效、补贴、奖金及其他福利等具体构成。 进行沟通时需要确认清楚是税前还是税后沟…...

【机器学习】Kaggle实战Rossmann商店销售预测(项目背景、数据介绍/加载/合并、特征工程、构建模型、模型预测)

文章目录 1、项目背景2、数据介绍3、数据加载3.1 查看数据3.2 空数据处理3.2.1 训练数据3.2.2 测试数据3.3.3 商店数据处理3.3.4 销售时间关系 4、合并数据5、特征工程6、构建训练数据和测试数据7、数据属性间相关性系数8、提取模型训练的数据集9、构建模型9.1 定义评价函数9.2…...

简化计算步骤以减少误差

简化计算步骤以减少误差 同样一个计算问题&#xff0c;若能减少运算次数&#xff0c;既可以节省计算机的计算时间&#xff0c;还可以减小舍人误差。 例 计算 x 255 x^{255} x255的值. 如果逐个相乘要用 254 次乘法&#xff0c;但若写成 x 255 x ⋅ x 2 ⋅ x 4 ⋅ x 8 ⋅…...

利用AI大模型和Mermaid生成流程图

核心点1&#xff1a;利用大模型生成流程图的语句&#xff08;Code&#xff09; 确定业务流程&#xff1a; 用户需要明确要绘制的业务流程&#xff0c;包括主要步骤、决策点以及各步骤之间的关系。将确定的业务流程以文字形式描述出来。 生成Mermaid代码&#xff1a; 将描述好的…...

SqlServer 杂项知识整理

目录 一. decimal字段类型二. 查询时加锁 一. decimal字段类型 ⏹decimal(8,3): 整数5位&#xff0c;小数3位。一共8位。 如果输入 20&#xff0c;会自动格式化为 20.000如果输入 20.1&#xff0c;会自动格式化为 20.100 -- 给数据库新增一个字段,类型要求是decimal类型 ALT…...

【Uniapp-Vue3】@import导入css样式及scss变量用法与static目录

一、import导入css样式 在项目文件中创建一个common文件夹&#xff0c;下面创建一个css文件夹&#xff0c;里面放上style.css文件&#xff0c;编写的是公共样式&#xff0c;我们现在要在App.vue中引入该样式。 在App.vue中引入该样式&#xff0c;这样就会使样式全局生效&#…...

Maven 中 scope=provided 和 optional=true 的区别

先说效果&#xff0c;maven依赖声明中加了<scope>provided</scope>&#xff0c;或者加了<optional>true</optional>&#xff0c;从效果上看是一样的&#xff0c;都会中断依赖传递&#xff0c;观察下图&#xff1a; 图中&#xff0c;项目B分别依赖了C和…...

自动化测试与智能化测试的区别和关系

自动化测试与智能化测试的区别和关系 在现代软件开发过程中&#xff0c;测试环节是保证软件质量的重要组成部分。随着技术的不断进步&#xff0c;传统的手工测试方法逐渐无法满足高效、精确的需求&#xff0c;自动化测试&#xff08;Automated Testing&#xff09;应运而生。近…...

django在线考试系统

Django在线考试系统是一种基于Django框架开发的在线考试平台&#xff0c;它提供了完整的在线考试解决方案。 一、系统概述 Django在线考试系统旨在为用户提供便捷、高效的在线考试环境&#xff0c;满足教育机构、企业、个人等不同场景下的考试需求。通过该系统&#xff0c;用…...

centos9设置静态ip

CentOS 9 默认使用 NetworkManager 管理网络&#xff0c;而nmcli是 NetworkManager 命令行接口的缩写&#xff0c;是一个用来进行网络配置、管理网络连接的命令工具&#xff0c;可以简化网络设置&#xff0c;尤其是在无头&#xff08;没有图形界面&#xff09;环境下。 1、 cd…...

使用postMessage解决iframe与父页面传参

接收传递的消息时&#xff0c;可以将 window.addEventListener(message, function(e) { console.log(e.data) }) 写法&#xff0c;更换为 window.onmessage async function(e) {} 可以避免消息发送后&#xff0c;多次接收该参数 父页面js IframeEvent(){const send …...

浅谈云计算05 | 云存储等级及其接口工作原理

一、云存储设备 在当今数字化飞速发展的时代&#xff0c;数据已然成为个人、企业乃至整个社会的核心资产。从日常生活中的珍贵照片、视频&#xff0c;到企业运营里的关键业务文档、客户资料&#xff0c;数据量呈爆炸式增长。面对海量的数据&#xff0c;如何安全、高效且便捷地存…...

DolphinScheduler自身容错导致的服务器持续崩溃重大问题的排查与解决

01 问题复现 在DolphinScheduler中有如下一个Shell任务&#xff1a; current_timestamp() { date "%Y-%m-%d %H:%M:%S" }TIMESTAMP$(current_timestamp) echo $TIMESTAMP sleep 60 在DolphinScheduler将工作流执行策略设置为并行&#xff1a; 定时周期调度设置…...

Linux 容器漏洞

定义&#xff1a;Linux 容器漏洞是指在容器技术&#xff08;如 Docker、LXC 等&#xff09;运行环境中存在的安全弱点。这些漏洞可能存在于容器镜像本身、容器运行时&#xff08;如 runc&#xff09;、容器编排工具&#xff08;如 Kubernetes&#xff09;或者容器与主机之间的交…...

前端依赖安装指南

前端依赖安装指南 一、NVM管理工具安装 1.在 Windows 上安装 下载 NVM for Windows 的安装程序&#xff1a;(最新版本可以在 nvm-windows Releases 页面 找到)运行下载的安装程序并按步骤操作。 2.配置 NVM exe安装自动配置环境变量 3. 验证 NVM 安装 验证 NVM 是否成功…...

滑动窗口限流算法:基于Redis有序集合的实现与优化

滑动窗口限流算法是一种基于时间窗口的流量控制策略&#xff0c;它将时间划分为固定大小的窗口&#xff0c;并在每个窗口内记录请求次数。通过动态滑动窗口&#xff0c;算法能够灵活调整限流速率&#xff0c;以应对流量的波动。 算法核心步骤 统计窗口内的请求数量&#xff1…...

JavaRestClient 客户端初始化+索引库操作

1. 介绍 ES官方提供了各种不同语言的客户端&#xff0c;用来操作ES。这些客户端的本质就是组装DSL语句&#xff0c;通过http请求发送给ES。 Elasticsearch目前最新版本是8.0&#xff0c;其java客户端有很大变化。不过大多数企业使用的还是8以下版本 2. 客户端初始化 在elastic…...