JS的那些坑
Posted 菜刚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS的那些坑相关的知识,希望对你有一定的参考价值。
本文总结了JS在日常使用和面试中需要注意的知识点。
变量提升
请看以下代码输出什么
showName()
console.log(myname)
var myname = 'hello world'
function showName()
console.log('函数showName被执行')
答案:
答案和我们印象中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
,10 / 0 = NaN
,NaN与任何数操作都是NaN,例如:NaN * 10会返回NaN。有人会问,那我判断一个变量值是否是NaN该如何做呢?其实JS提供了内置函数isNaN()
函数参数
请看以下代码输出什么?
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
, 1 + undefined
为NaN
(not a number)
函数名
请看以下代码,存在两个相同的函数名,在代码运行后,会输出什么?
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的变量值可分为:基本类型
和引用类型
两种;其中,基本类型
值是简单的数据段,包含 underfined
、Null
、Boolean
、Number
和String
这五种,其余为引用类型。
这两种类型的值在进行变量间赋值的时候,也会有所不同。对于值是基本类型
的变量,在赋值的时候,会在给赋值变量复制一个新值。例如上题中的var num2 = num1
这时,是将num1的值复制一份,填写给num2
,相当于:var num2 = 5
。
但是,如果是引用类型
的变量,在赋值的时候,各种变量还会指向原引用。例如代码中的var obj2 = obj1
,此时obj2
和obj1
同时指向了同一个object。
更多精彩内容,请关注我的公众号
以上是关于JS的那些坑的主要内容,如果未能解决你的问题,请参考以下文章