JavaScript-Basic Day2-5 Notes
1、如何理解 == 和 === 潜在区别?
console.log(3 == '3')
console.log(3 === '3')
在 JavaScript 中,== 和 === 是两种不同的比较操作符,它们在比较两个值时的行为有所不同:
-
双等号(
==) - 抽象相等运算符- 这个运算符在比较两个值时会进行类型转换。如果两个值的类型不同,JavaScript 会尝试将它们转换为相同的类型,然后再进行比较。
- 在你的例子中:
console.log(3 == '3'),数字3和字符串'3'类型不同,但 JavaScript 会将字符串'3'转换为数字3,然后比较这两个数字。由于转换后的值相同,所以这个表达式的结果是true。
-
三等号(
===) - 严格相等运算符- 这个运算符在比较两个值时不会进行类型转换。它要求两个值的类型和值都必须相同,才会返回
true。 - 在你的例子中:
console.log(3 === '3'),尽管数字3和字符串'3'的内容相同,但它们的类型不同(一个是数字类型,另一个是字符串类型),因此这个表达式的结果是false。
- 这个运算符在比较两个值时不会进行类型转换。它要求两个值的类型和值都必须相同,才会返回
总结
- 使用
==时,如果值的类型不同,JavaScript 会进行类型转换后再比较。 - 使用
===时,如果值的类型不同,比较结果直接为false,不会进行类型转换。
在编写 JavaScript 代码时,推荐使用 === 来避免因隐式类型转换导致的意外结果,这样可以使得代码的逻辑更加清晰和可预测。
2、为什么如下两行代码会分别返回3,4
let arr = ['pink', 'hotpink'] console.log(arr.push('yellow')) //3 console.log(arr.push('blue')) //4
在 JavaScript 中,Array.prototype.push() 方法用于将一个或多个元素添加到数组的末尾,并返回数组新的长度。
3、如何理解这个unshift() 这个单词为什么和向前插入能够建立联系呢?
unshift 这个单词由两部分组成:"un-" 和 "shift"。
-
"shift" 在英语中意味着移动或转移。在编程语境下,"shift" 通常用来描述从数据结构(如数组)的一端移除元素的操作。例如,JavaScript 中的
shift()方法就是从数组的开头移除第一个元素。 -
"un-" 是一个前缀,表示相反或反向的动作。
结合这两部分,unshift 字面上可以理解为“做 shift 的相反动作”,即不是从一端移除元素,而是向相反的方向,也就是数据结构的开头添加元素。
在 JavaScript 中,Array.prototype.unshift() 方法正是这样的操作:它允许你向数组的开头添加一个或多个元素。当使用 unshift 方法时,任何新添加的元素都会被插入到数组已有元素的前面,而原有元素则向后移动。
let arr = ['pink', 'hotpink']; arr.unshift('red'); console.log(arr);
- 初始时,
arr是['pink', 'hotpink']。 arr.unshift('red')将'red'插入到数组的开头。- 执行后,
arr变为['red', 'pink', 'hotpink']。
unshift 方法不仅在数组开头添加了元素,还返回了新数组的长度。在这个例子中,数组的长度从 2 增加到了 3。
4、请逐行解释下如下CSS代码
* { margin: 0; padding: 0; } .box { display: flex; width: 700px; height: 300px; border-left: 1px solid pink; border-bottom: 1px solid pink; margin: 50px auto; justify-content: space-around; align-items: flex-end; text-align: center; } .box > div { display: flex; width: 50px; background-color: pink; flex-direction: column; justify-content: space-between; } .box div span { margin-top: -20px; } .box div h4 { margin-bottom: -35px; width: 70px; margin-left: -10px; }
这段 CSS 代码包含了几个选择器和对应的样式规则,下面是逐行的解释:
-
*这是一个通配符选择器,它匹配页面上的所有元素。
* { margin: 0; padding: 0; }
margin: 0;将所有元素的外边距设置为 0。padding: 0;将所有元素的内边距设置为 0。- 这通常用于重置浏览器的默认样式,以确保页面元素的样式从头开始设置,避免不同浏览器之间的样式差异。
2.box 这是一个类选择器,匹配所有具有 class="box" 的元素。
.box { display: flex; width: 700px; height: 300px; border-left: 1px solid pink; border-bottom: 1px solid pink; margin: 50px auto; justify-content: space-around; align-items: flex-end; text-align: center; }
display: flex;将元素的显示类型设置为 flex,启用 Flexbox 布局。width: 700px;设置元素的宽度为 700 像素。height: 300px;设置元素的高度为 300 像素。border-left: 1px solid pink;设置元素左边框为 1 像素宽、实线、粉色。border-bottom: 1px solid pink;设置元素底边框为 1 像素宽、实线、粉色。margin: 50px auto;设置元素的外边距,上下方为 50 像素,左右自动(常用于水平居中元素)。justify-content: space-around;在 Flex 容器中,所有项目(子元素)沿着主轴(默认是水平方向)均匀分布,项目间的空间比项目与容器边缘的空间大一倍。align-items: flex-end;所有子元素在交叉轴(垂直方向)的末端对齐。text-align: center;文本内容在元素内水平居中显示。
3..box > div 这是一个子选择器,匹配所有 .box 元素的直接子 div 元素。
.box > div { display: flex; width: 50px; background-color: pink; flex-direction: column; justify-content: space-between; }
4..box div span 这是一个后代选择器,匹配所有 .box 元素后代中的 span 元素。
.box div span { margin-top: -20px; }
margin-top: -20px;设置span元素的上外边距为 -20 像素,这通常用于调整元素的位置,使其向上移动。
5 .box div h4 这是一个后代选择器,匹配所有 .box 元素后代中的 h4 元素。
.box div h4 { margin-bottom: -35px; width: 70px; margin-left: -10px; }
margin-bottom: -35px;设置h4元素的下外边距为 -35 像素,这通常用于调整元素的位置,使其向下移动。width: 70px;设置h4元素的宽度为 70 像素。margin-left: -10px;设置h4元素的左外边距为 -10 像素,这通常用于调整元素的水平位置,使其向左移动。
5、记住justify-content: space-around 和 space-between之间的区别
space-between会区间两头两尾顶齐。

justify-content: space-around 则会在两头两位之间流出一段距离。

6、解释下如下函数的寻值num的顺序,这是不是有些闭包的含义在里面?和python的闭包有何异同?
<script> let num = 10 function fn(){ let num = 20 // 如果注释这行,会打印出10 function func(){ let num = 30 // 如果注释这行,会打印出20。 如果都不注释,按作用域就近取值,会打印出30 console.log(num) } func() } fn() </script>
这段 JavaScript 代码展示了作用域链和闭包的概念。首先,让我们逐步解释函数的执行和 num 的查找顺序:
-
你声明了一个全局变量
num并赋值为10。 -
你定义了一个函数
fn,在fn函数内部:- 又声明了一个局部变量
num并赋值为20。 - 定义了一个嵌套函数
func,在func函数内部:- 再次声明了一个局部变量
num并赋值为30。 - 使用
console.log(num)打印num的值。
- 再次声明了一个局部变量
- 又声明了一个局部变量
-
当你调用
fn()时,fn函数执行:- 首先创建了
fn的作用域,其中包含变量num(值为20)。 - 接着
fn调用了内部的func函数,创建了func的作用域,其中包含变量num(值为30)。 func执行时,console.log(num)打印的是func作用域内的num,因此输出结果是30。
- 首先创建了
闭包的概念
闭包是指函数可以记住并访问其创建时的作用域,即使该函数在其原始作用域之外被执行。
在这个例子中,func 函数在其创建时的作用域(fn 函数的作用域)之外被调用,但它仍然可以访问 fn 函数作用域内的变量。
JavaScript 闭包与 Python 闭包的异同
-
相同点:
- 两者都允许函数访问创建时的作用域中的变量,即使函数在其原始作用域之外被调用。
- 两者都可以用于创建具有私有变量的函数。
-
不同点:
- 语法:JavaScript 和 Python 的语法不同,这影响了闭包的写法。
- 作用域规则:Python 有明确的块作用域概念,而 JavaScript 有函数作用域和词法作用域。
- 类型系统:Python 是动态类型语言,而 JavaScript 也是动态类型语言,但它们的类型系统和类型推断机制可能有所不同。
- 执行环境:Python 通常用于科学计算、数据分析等领域,而 JavaScript 主要用于网页开发,执行环境主要是浏览器或 Node.js。
在你提供的代码示例中,闭包的使用允许 func 函数记住并访问它被创建时的变量 num(值为 30),即使它在 fn 函数被调用后才执行。
这种特性在 JavaScript 中非常有用,尤其是在处理异步操作、封装私有变量和方法等场景。
7、关于匿名函数、具名函数如下细节需要注意。
fn(1, 2) // 匿名函数没有函数提升, 无法先调用,后定义。 这样执行必然报错 let fn = function (x, y){ //事实上,只要加了let, 必须先声明后使用 console.log(x + y) } funcAdd(1, 5) // 具名函数有函数提升,可以这样成功执行。[具名函数调用可以写在任何位置] function funcAdd(x, y){ console.log(x + y) }
总结:
1. 具名函数的调用可以写到任何位置;
2. 函数表达式,必须先声明函数表达式,后调用。
8、关于立即执行函数的理解,和使用
作用:
1、立即执行函数可以防止变量污染,即便好几个同名变量,因为都是局部变量,所以不会互相干扰;
2、立即执行函数不需要额外调用,语法中已经就包括调用了;
两种语法:(1). (function(形参){})(实参) (2). (function(形参){}(实参)) 其实分辨就是看后面调用的括号是写在里面,还是写在外面。
对外表现为,是一个括号,还是两个括号。
注意:多个立即执行函数之间,需要用封号隔开;
例如如下代码的多个变量,虽然重名,但也不会产生触痛
(function (x, y){ console.log(x + y) })(1, 2); (function (x, y){ console.log(x + y) })(3, 4); (function(){ let num1 = 10 let num2 = 20 console.log(num1 + num2) }()); (function(){ let num1 = 10 let num2 = 20 console.log(num1 + num2) }());
9、Boolean转化如下几个特殊值的时候,需要注意下
console.log(Boolean(undefined)) //false console.log(Boolean(null)) //false console.log(Boolean(NaN)) //false
10、 JavaScript的如下循环和python还不太一样,注意区分下。
let arr = ['pink', 'red', 'blue'] // for(let k in arr){ // // console.log(k) // 这样返回的是索引0,1,2。和python不一样 // // console.log(arr[k]) // console.log(arr[k]) // } let obj = { uname: 'bruce老师', age: 18, gender: '男' } for(let k in obj){ // console.log(k) // 这样返回的是uname, age, gender。和python不一样 // console.log(obj.uname) // console.log(obj.k) // console.log(obj.'uname') // console.log(obj['uname']) console.log(obj[k]) }
11、关于变量和对象的共享内存问题,如下的例子可以体会下。
<script> let num1 = 10 let num2 = num1 num2 = 20 console.log(num1) // 10, 变量并不会共享同一块内存 let obj1 = { age: 18 } let obj2 = obj1 obj2.age = 20 console.log(obj1.age) // 20, 但是这里的object会共享同一块内存 </script>

浙公网安备 33010602011771号