1

JS的那些坑(一)

 2 years ago
source link: https://i6448038.github.io/2022/03/19/js-learning-1/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

JS的那些坑(一)

2022-03-19

本文总结了JS在日常使用和面试中需要注意的知识点。

变量提升

请看以下代码输出什么

showName()
console.log(myname)
var myname = 'hello world'
function showName() {
console.log('函数showName被执行')
}

答案

image.png

答案和我们印象中js自上而下的执行顺序有些出入,这是由于js为了开发者写代码方便而省略掉的变量声明部分,而在编译阶段会将此部分补充完整,而开发者习惯了“简洁版”,并延续了”简洁版”的思路而产生的错觉。
现在,我们把”省去”的声明代码还原,就能发现端倪:

首先看变量的“全貌”:

var myname = 'hello world'

var myname //声明部分

myname = 'hello world' //赋值部分

再看看函数的“全貌”:

// 把声明提前
function showName() {
console.log('函数showName被执行')
}

//执行部分
showName()

在这里,以上函数showName是一个完整的函数声明,没有赋值操作,而如下函数声明,是声明与赋值分开的:


var showName = function(){
console.log("函数showName被执行")
}

等同于如下操作:

// 声明
var showName = undefined

// 赋值
showName = function(){
console.log("函数showName被执行")
}

所谓的变量提升,是指在 JavaScript 代码执行过程中,JavaScript 引擎把变量的声明部分和函数的声明部分提升到代码开头的“行为”。变量被提升后,会给变量设置默认值,这个默认值就是我们熟悉的 undefined。

script标签

请看以下代码,将输出什么?

<script type="text/javascript">
console.log("1")
console.log("</script>")
console.log("2")
</script>

答案:程序报错

包含在<script>标签的内容,将会被浏览器顺序执行,直到遇到</script>;特别注意:不要在代码的任何地方出现“</script>”字符串,只要一出现,浏览器的解释器就认为是代码终止符到了,后续内容将不再解析;应该换为“<\/script>”,这样浏览器会对内容做一个转义,程序就能正常运行了。

undefined

JS整个语言只有六种数据类型:undefined、Null、Boolean、Number、String以及Object,JS不支持自定义类型的机制。

请看以下代码,试问返回什么


var message

alert(message)
alert(age)

答案显而易见:在进行alert(age)的时候,报错了;那再看看如下代码,请问会输出什么:

var message

alert(typeof message)
alert(typeof age)

答案可能很意外,会弹出两次undefined,而且不报错。

可能让人感到很奇怪,但事实却是如此;对未初始化的变量进行typeof操作符会返回undefined的,对未定义的变量进行typeof操作也是会返回undefined;可能背后的逻辑是:无论变量是否定义,都不会真正执行吧

NaN

请看以下代码输出什么?

console.log(NaN === NaN)

正确答案是:false

NaN的含义是:“Not a Number”;是一个特殊的值,这个数值表示一个本来返回数值的操作数未返回数值的情况,以替代直接报错。例如:“10 / 0” 在其他语言中直接就报错了,但是JS为了防止程序报错崩溃,加入了NaN


## 函数参数
请看以下代码输出什么?

```js
function sum(num1, num2){
return num1 + num2
}

let a = sum(1)
console.log(a)

会报错吗?
正确答案是:输出NaN

js函数的参数与绝大多数语言中的参数不同,js对函数参数的类型和个数都没有强制限制;在js内部,函数参数的实现是拿一个数组来表示的;因此,哪怕你定义了两个参数,只传进去一个参数,也不影响js的正常运行。
写代码的时候,在js的函数体内部,可以通过arguments对象来访问js的参数数组,从而获取传递给函数的每一个参数。

再来看看以上这道题目,sum函数有俩参数,但是只传了一个参数,程序不会报错,原因不解释了。在sum函数中,程序变为了 1 + arguments[1],由于 arguments[1]为传参,故值为undefined,


## 函数名

请看以下代码,存在两个相同的函数名,在代码运行后,会输出什么?

```js
function addNum(num) {
return num + 10
}

function addNum(num) {
return num + 20
}

let num = addNum(1)
console.log(num)

正确答案:输出21

其他语言中例如Java,只要定义函数签名或者函数参数类型和数量不同,就可以定义相同的函数名,这是传统意义上的重载,但是JS中没有重载,如果定义了两个以上相同的函数名,JS最终会以最后定义的函数为准。

请看一下代码,最终会输出什么?

var num1 = 5
var num2 = num1
num2 = num2 + 1
console.log(num1)


var obj1 = new Object()
var obj2 = obj1
obj2.name = "ryugou"
console.log(obj1.name)

正确答案:

5
ryugou

js的变量值可分为:基本类型引用类型两种;其中,基本类型值是简单的数据段,包含 underfinedNullBooleanNumberString这五种,其余为引用类型。
这两种类型的值在进行变量间赋值的时候,也会有所不同。对于值是基本类型的变量,在赋值的时候,会在给赋值变量复制一个新值。例如上题中的var num2 = num1 这时,是将num1的值复制一份,填写给num2,相当于:var num2 = 5
但是,如果是引用类型的变量,在赋值的时候,各种变量还会指向原引用。例如代码中的var obj2 = obj1,此时obj2obj1同时指向了同一个object。

更多精彩内容,请关注我的公众号

795aa185e1914591812cf61fb521ea65~tplv-k3u1fbpfcp-zoom-1.image


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK