目录
- 1.1:html5有哪些新特性?
- 1.2:如何处理HTML5新标签的浏览器兼容问题?
- 1.3:如何区分 HTML 和 HTML5?
- 2.浏览器的渲染过程
- 3.DOM怎样添加、移除、移动、复制、创建和查找节点
- 4.解释盒模型宽高值的计算方式,边界塌陷,负值作用,box-sizing概念
- 5.this对象的理解
- 6.JavaScript事件模型
- 7.Doctype作用? 严格模式与混杂模式-如何触发这两种模式,区分它们有何意义?
- 8.CSS3有哪些新特性?
- 9.介绍一下你对浏览器内核的理解?
- 10.JavaScript的作用域和作用域链
- 11.浏览器的垃圾回收机制
- 12.vue生命周期
- 13.js数组主要有哪些方法?主要参数有哪些?
- 14.null和undefined的区别?
1.1:html5有哪些新特性?
(1)新增语义标签
<article>
定义文章内容
<details>
关于文档的细节
<aside>
标签定义<article>
标签外的内容。
aside 的内容应该与附近的内容相关。
<summary>
与<details>
一起使用。<summary>
标签为 <details>
元素定义一个可见的标题。
<details>
<summary>Copyright 1999-2011.</summary>
<p> - by Refsnes Data. All Rights Reserved.</p>
<p>All content and graphics on this web site are the property of the company Refsnes Data.</p>
</details>
<figure>
<figcaption>
img和figcaption组合放在figure里
<figure>
//img和figcaption可以组合放在figure里
//<figcaption> 标签为 <figure> 元素定义标题。
<img src="xxxx.jpg" alt="The Pulpit Rock" width="304" height="228">
<figcaption>Fig1. - The Pulpit Rock, Norway.</figcaption>
</figure>
<mark>
突出显示部分文本
<time>
为时间和日期使用
<p>我们在每天早上 <time>9:00</time> 开始营业。</p>
<p>我在 <time datetime="2016-02-14">情人节</time> 有个约会。</p>
(2)新增的input类型和属性
(3)新的图形标签 SVG
SVG
代表可缩放矢量图形
SVG用于为Web定义图形
SVG是W3C的建议
SVG与Canvas区别
SVG适用于描述XML中的2D图形的语言
Canvas随时随地绘制2D图形(使用JavaScript)
SVG是基于XML的,这意味着每个元素在SVG DOM中都可用。你可以为每个元素添加JavaScript事件处理程序
在SVG中,每个绘制的形状都会被记忆为一个对象。如果SVG对象的书香发生变化,浏览器可以自动重新渲染形状。
Canvas是一像素一像素地渲染。在画布中,一旦图形绘制好了,就会被浏览器遗忘。如果你想改变某一个的位置,整个场景都需要重新绘制,包括可能已经被图形覆盖的任何对象。
(4)新的多媒体标签
(5)新的HTML5的API
HTML Geolocation 地理位置
HTML Drag & Drop拖放
HTML Local Storage 本地存储
HTML Application Cache 应用程序缓存
HTML Web Workers web工作者
HTNL SSE
(6)HTML5删除/废弃不能用的元素
1.2:如何处理HTML5新标签的浏览器兼容问题?
使用静态资源的html5shiv包
只需要在head中调用:
<!--[if lt IE9]>
<script src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->
1.3:如何区分 HTML 和 HTML5?
(1)文档声明和编码不同
声明:
HTML5:<!Doctype html>
HTML4:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">"
编码:
HTML5:<meta charset="UTF-8">
HTML4:<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
可见HTML5的声明更加简洁。
(2)HTML5具有语义化标签
(3)HTML5具有“特色标签”
2.浏览器的渲染过程
- 解析HTML文档,构建DOM树
- 处理CSS标记,构成层叠样式表模型CSSOM(CSS Object Model)。
- 构建渲染树。将DOM和CSSOM合并为渲染树(rendering tree)将会被创建,代表一系列将被渲染的对象。
- 渲染树布局。渲染树的每个元素包含的内容都是计算过的,它被称之为布局layout。浏览器使用一种流式处理的方法,只需要一次pass绘制操作就可以布局所有的元素。
- 渲染树绘制。将渲染树的各个节点绘制到屏幕上,这一步被称为绘制painting.
注:以上五个步骤并不一定一次性顺序完成,CSS和JS存在重绘和回流。
3.DOM怎样添加、移除、移动、复制、创建和查找节点
(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
详情点击这里。
4.解释盒模型宽高值的计算方式,边界塌陷,负值作用,box-sizing概念
(1)盒模型宽高
content-box:盒子定义宽高 = 内容宽高(content)
border-box:盒子定义宽高 = 内容宽高(content) + 内边距 (padding)+ 边框(border)
(2)边界塌陷
在标准文档流中,竖直方向(记住是竖直方向,左右方向的不会出现塌陷现象)的margin会出现叠加现象,即较大的margin会覆盖掉较小的margin,竖直方向的两个盒子中间只有一个较大的margin,这就是margin的塌陷现象。
举例1 兄弟元素的边界塌陷
<!-- html代码 -->
<div class="up">我是上面的盒子</div>
<div class="down">我是下面的盒子</div>
/* css代码 */
div.up{
width: 100px;
height: 100px;
margin: 100px;
background: #ff6600;
}
div.down{
width: 100px;
height: 100px;
margin: 100px;
background: aquamarine;
}
根据代码应该是200px,但结果是100px
举例2 父子元素
<div class="parent">
<!-- 父亲的颜色是橙色 -->
<div class="child">我是儿</div>
<!-- 儿子的颜色是浅绿色 -->
</div>
/* css代码 */
div.parent{
width: 200px;
height: 200px;
margin-top: 50px;
background: #ff6600;
}
div.child{
width: 50px;
height: 50px;
margin-top: 100px;
background: aquamarine;
}
根据代码应该是150px(parent 50px +child 100px) 但结果是100px。父亲的50px被覆盖了
(3)margin 负值作用
使自身反方向移动。 例如margin-top: -100px; 即向上移动100px。
(4)box-sizing概念
定义:box-sizing:允许您以特定的方式定义匹配某个区域的特定元素(W3C上的原话 )
语法:box-sizing:content-box|border-box
即设置指定元素的盒模型
5.this对象的理解
this的指向
this表示当前对象,this的指向是根据调用的上下文来决定的,默认指向window对象,指向window对象时可以省略不写,例如:
this.alert() <=> window.alert()<=> alert();
调用的上下文环境包括全局和局部
全局环境
全局环境就是在里面,这里的this始终指向的是window对象。
<script>
console.log(<strong>this</strong>);//指向window对象
</script>
局部环境
1)在全局作用域下直接调用函数,this指向window
function func(){
console.log(this) ;//this指向的还是window对象
}
func();
2)对象函数调用,哪个对象调用就指向哪个对象
<input type="button"id="btnOK" value="OK">
<script>
varbtnOK=document.getElementById("btnOK");
btnOK.οnclick=function(){
console.log(this);//this指向的是btnOK对象
}
</script>
3)使用 new 实例化对象,在构造函数中的this指向实例化对象。
var Show=function(){
this.myName="Mr.Cao"; //这里的this指向的是obj对象
}
var obj=new Show();
4)使用call或apply改变this的指向
var Go=function(){
this.address="深圳";
}
var Show=function(){
console.log(this.address);//输出 深圳
}
var go=new Go();
Show.call(go);//改变Show方法的this指向go对象
6.JavaScript事件模型
JavaScript事件模型主要分为3种:原始事件模型、DOM2事件模型、IE事件模型。
原始事件模型
这是一种被所有浏览器都支持的事件模型,对于原始事件而言,没有事件流,事件一旦发生将马上进行处理,有两种方式可以实现原始事件:
(1)在html代码中直接指定属性值:
(2)在js代码中为 document.getElementsById(“demo”).onclick = doSomeTing()
优点:所有浏览器都兼容
缺点:1)逻辑与显示没有分离;2)相同事件的监听函数只能绑定一个,后绑定的会覆盖掉前面的,如:a.onclick = func1; a.onclick = func2;将只会执行func2中的内容。3)无法通过事件的冒泡、委托等机制完成更多事情。
因为这些缺点,虽然原始事件类型兼容所有浏览器,但仍不推荐使用。
DOM2事件模型
此模型是W3C制定的标准模型,现代浏览器(IE6~8除外)都已经遵循这个规范。W3C制定的事件模型中,一次事件的发生包含三个过程:
(1).事件捕获阶段,(2).事件目标阶段,(3).事件冒泡阶段。如下图所示
事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。
事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
事件冒泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。
所有的事件类型都会经历事件捕获但是只有部分事件会经历事件冒泡阶段,例如submit事件就不会被冒泡。
事件的传播是可以阻止的:
• 在W3c中,使用stopPropagation()方法
• 在IE下设置cancelBubble = true;
在捕获的过程中stopPropagation();后,后面的冒泡过程就不会发生了。
标准的事件监听器该如何绑定:
addEventListener(“eventType”,“handler”,“true|false”);其中eventType指事件类型,注意不要加‘on’前缀,与IE下不同。第二个参数是处理函数,第三个即用来指定是否在捕获阶段进行处理,一般设为false来与IE保持一致(默认设置),除非你有特殊的逻辑需求。监听器的解除也类似:removeEventListner(“eventType”,“handler”,“true!false”);
IE事件模型
IE不把该对象传入事件处理函数,由于在任意时刻只会存在一个事件,所以IE把它作为全局对象window的一个属性,为求证其真伪,使用IE8执行代码alert(window.event),结果弹出是null,说明该属性已经定义,只是值为null(与undefined不同)。难道这个全局对象的属性是在监听函数里才加的?于是执行下面代码:
window.onload = function (){alert(window.event);}
setTimeout(function(){alert(window.event);},2000);
结果第一次弹出【object event】,两秒后弹出依然是null。由此可见IE是将event对象在处理函数中设为window的属性,一旦函数执行结束,便被置为null了。IE的事件模型只有两步,先执行元素的监听函数,然后事件沿着父节点一直冒泡到document。冒泡已经讲解过了,这里不重复。IE模型下的事件监听方式也挺独特,绑定监听函数的方法是:attachEvent( “eventType”,“handler”),其中evetType为事件的类型,如onclick,注意要加’on’。解除事件监听器的方法是 detachEvent(“eventType”,“handler” )
IE的事件模型已经可以解决原始模型的三个缺点,但其自己的缺点就是兼容性,只有IE系列浏览器才可以这样写。
以上就是3种事件模型,在我们写代码的时候,为了兼容ie,通常使用以下写法:
var demo = document.getElementById('demo');
if(demo.attachEvent){
demo.attachEvent('onclick',func);
}else{
demo.addEventListener('click',func,false);
}
7.Doctype作用? 严格模式与混杂模式-如何触发这两种模式,区分它们有何意义?
Doctype作用
DOCTYPE是document type (文档类型) 的缩写。声明位于文档的最前面,处于标签之前,它不是html标签。主要作用是告诉浏览器的解析器使用哪种HTML规范或者XHTML规范来解析页面。
删除<!DOCTYPE>会发生什么?
在W3C标准出来之前,不同的浏览器对页面渲染有不同的标准,产生了一定的差异。这种渲染方式叫做混杂模式。
在W3C标准出来之后,浏览器对页面的渲染有了统一的标准,这种渲染方式叫做标准模式。
<!DOCTYPE>不存在或者形式不正确会导致HTML或XHTML文档以混杂模式呈现,就是把如何渲染html页面的权利交给了浏览器,有多少种浏览器就有多少种展示方式。因此要提高浏览器兼容性就必须重视<!DOCTYPE>。
如何区分:浏览器解析时到底使用严格模式还是混杂模式,与网页中的 DTD 直接相关。
1、如果文档包含严格的 DOCTYPE ,那么它一般以严格模式呈现。(严格 DTD ——严格模式)
2、包含过渡 DTD 和 URI 的 DOCTYPE ,也以严格模式呈现,但有过渡 DTD 而没有 URI (统一资源标识符,就是声明最后的地址)会导致页面以混杂模式呈现。(有 URI 的过渡 DTD ——严格模式;没有 URI 的过渡 DTD ——混杂模式)
3、DOCTYPE 不存在或形式不正确会导致文档以混杂模式呈现。(DTD不存在或者格式不正确——混杂模式)
4、HTML5 没有 DTD ,因此也就没有严格模式与混杂模式的区别,HTML5 有相对宽松的语法,实现时,已经尽可能大的实现了向后兼容。( HTML5 没有严格和混杂之分)
8.CSS3有哪些新特性?
新增选择器 p:nth-child(n){color: rgba(255, 0, 0, 0.75)}
弹性盒模型 display: flex;
多列布局 column-count: 5;
媒体查询 @media (max-width: 480px) {.box: {column-count: 1;}}
个性化字体 @font-face{font-family:BorderWeb;src:url(BORDERW0.eot);}
颜色透明度 color: rgba(255, 0, 0, 0.75);
圆角 border-radius: 5px;
渐变 background:linear-gradient(red, green, blue);
阴影 box-shadow:3px 3px 3px rgba(0, 64, 128, 0.3);
倒影 box-reflect: below 2px;
文字装饰 text-stroke-color: red;
文字溢出 text-overflow:ellipsis;
背景效果 background-size: 100px 100px;
边框效果 border-image:url(bt_blue.png) 0 10;
旋转 transform: rotate(20deg);
倾斜 transform: skew(150deg, -10deg);
位移 transform:translate(20px, 20px);
缩放 transform: scale(。5);
平滑过渡 transition: all .3s ease-in .1s;
动画 @keyframes anim-1 {50% {border-radius: 50%;}} animation: anim-1 1s;
9.介绍一下你对浏览器内核的理解?
主要分成两个部分:
渲染引擎(Render Engine)
和JS引擎。
渲染引擎:负责取得网页的内容(html,xml和图像等),整理讯息(例如假如css),以及计算网页的显示方式,然后输出到显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不同。所有网页浏览器、电子邮件客户端以及它需要编辑、显示网络内容的应用程序都需要内核。
JS引擎:解析和执行JavaScript来实现网页的动态效果。
最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向与只指渲染引擎。
常见的浏览器内核有哪些?
Trident(IE内核):IE,360,搜过浏览器;
Gecko(Firefox内核):Netscape6及以上版本,
Presto内核:Opera
Blink内核:Opera;
Webkit(Safari内核,Chrome内核原型,开源):Safari,Chrome
10.JavaScript的作用域和作用域链
- 什么是作用域
作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用域决定了代码区块中变量和其他资源的可见性。可能这两句话并不好理解,我们先来看个例子:
function outFun2() {
var inVariable = "内层变量2";
}
outFun2();//要先执行这个函数,否则根本不知道里面是啥
console.log(inVariable); // Uncaught ReferenceError: inVariable is not defined
从上面的例子可以体会到作用域的概念,变量 inVariable 在全局作用域没有声明,所以在全局作用域下取值会报错。我们可以这样理解:作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 的到来,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。
- 全局作用域和函数作用域
在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:
最外层函数 和在最外层函数外面定义的变量拥有全局作用域
var outVariable = "我是最外层变量"; //最外层变量
function outFun() { //最外层函数
var inVariable = "内层变量";
function innerFun() { //内层函数
console.log(inVariable);
}
innerFun();
}
console.log(outVariable); //我是最外层变量
outFun(); //内层变量
console.log(inVariable); //inVariable is not defined
innerFun(); //innerFun is not defined
所有末定义直接赋值的变量自动声明为拥有全局作用域
function outFun2() {
variable = "未定义直接赋值的变量";
var inVariable2 = "内层变量2";
}
outFun2();//要先执行这个函数,否则根本不知道里面是啥
console.log(variable); //未定义直接赋值的变量
console.log(inVariable2); //inVariable2 is not defined
所有 window 对象的属性拥有全局作用域
一般情况下,window 对象的内置属性都拥有全局作用域,例如 window.name、window.location、window.top 等等。
全局作用域有个弊端:如果我们写了很多行 JS 代码,变量定义都没有用函数包括,那么它们就全部都在全局作用域中。这样就会 污染全局命名空间, 容易引起命名冲突。
// 张三写的代码中
var data = {a: 100}
// 李四写的代码中
var data = {x: true}
这就是为何 jQuery、Zepto 等库的源码,所有的代码都会放在(function(){…})()中。因为放在里面的所有变量,都不会被外泄和暴露,不会污染到外面,不会对其他的库或者 JS 脚本造成影响。这是函数作用域的一个体现。
函数作用域,是指声明在函数内部的变量,和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部。
function doSomething(){
var blogName="浪里行舟";
function innerSay(){
alert(blogName);
}
innerSay();
}
alert(blogName); //脚本错误
innerSay(); //脚本错误
作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。我们看个例子,用泡泡来比喻作用域可能好理解一点:
最后输出的结果为 2, 4, 12
泡泡 1 是全局作用域,有标识符 foo;
泡泡 2 是作用域 foo,有标识符 a,bar,b;
泡泡 3 是作用域 bar,仅有标识符 c。
- 块级作用域
块级作用域可通过新增命令 let 和 const 声明,所声明的变量在指定块的作用域外无法被访问。块级作用域在如下情况被创建:
在一个函数内部
在一个代码块(由一对花括号包裹)内部
let 声明的语法与 var 的语法一致。你基本上可以用 let 来代替 var 进行变量声明,但会将变量的作用域限制在当前代码块中。
循环中的绑定块作用域的妙用
<script>
<button>测试1</button>
<button>测试2</button>
<button>测试3</button>
<script type="text/javascript">
var btns = document.getElementsByTagName('button')
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
console.log('第' + (i + 1) + '个')
}
}
</script>
我们要实现这样的一个需求: 点击某个按钮, 提示"点击的是第 n 个按钮",此处我们先不考虑事件代理,万万没想到,点击任意一个按钮,后台都是弹出“第4个”,这是因为 i 是全局变量,执行到点击事件时,此时 i 的值为 3。
那该如何修改,最简单的是用 let 声明 i。
作用域链
1.什么是自由变量
首先认识一下什么叫做 自由变量 。如下代码中,console.log(a)要得到 a 变量,但是在当前的作用域中没有定义 a(可对比一下 b)。当前作用域没有定义的变量,这成为 自由变量 。自由变量的值如何得到 —— 向父级作用域寻找(注意:这种说法并不严谨,下文会重点解释)。
var a = 100
function fn() {
var b = 200
console.log(a) // 这里的a在这里就是一个自由变量
console.log(b)
}
fn()
- 什么是作用域链
如果父级也没呢?再一层一层向上寻找,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是 作用域链 。
var a = 100
function F1() {
var b = 200
function F2() {
var c = 300
console.log(a) // 自由变量,顺作用域链向父作用域找
console.log(b) // 自由变量,顺作用域链向父作用域找
console.log(c) // 本作用域的变量
}
F2()
}
F1()
- 关于自由变量的取值
关于自由变量的值,上文提到要到父作用域中取,其实有时候这种解释会产生歧义。
var x = 10
function fn() {
console.log(x)
}
function show(f) {
var x = 20
(function() {
f() //10,而不是20
})()
}
show(fn)
在 fn 函数中,取自由变量 x 的值时,要到哪个作用域中取?——要到创建 fn 函数的那个作用域中取,无论 fn 函数将在哪里调用。
所以,不要在用以上说法了。相比而言,用这句话描述会更加贴切:要到创建这个函数的那个域。
作用域中取值,这里强调的是“创建”,而不是“调用”,切记切记——其实这就是所谓的"静态作用域"
var a = 10
function fn() {
var b = 20
function bar() {
console.log(a + b) //30
}
return bar
}
var x = fn(),
b = 200
x() //bar()
fn()返回的是 bar 函数,赋值给 x。执行 x(),即执行 bar 函数代码。取 b 的值时,直接在 fn 作用域取出。取 a 的值时,试图在 fn 作用域取,但是取不到,只能转向创建 fn 的那个作用域中去查找,结果找到了,所以最后的结果是 30。
11.浏览器的垃圾回收机制
一、垃圾回收机制原理
由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。
二、垃圾回收原理浅析
现在各大浏览器通常用采用的垃圾回收有两种方法:标记清除、引用计数。
1、标记清除(mark and sweep)
大部分浏览器以此方式进行垃圾回收,当变量进入执行环境(函数中声明变量,执行时)的时候,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”,在离开环境之后还有的变量则是需要被回收的变量。标记方式不定,可以是某个特殊位的反转或维护一个列表等。
垃圾收集器给内存中的所有变量都加上标记,然后去掉环境中的变量以及被环境中的变量引用的变量的标记。在此之后再被加上的标记的变量即为需要回收的变量,因为环境中的变量已经无法访问到这些变量。
工作流程:
-
垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记。
-
去掉环境中的变量以及被环境中的变量引用的变量的标记。
-
再被加上标记的会被视为准备删除的变量。
-
垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。
2、引用计数:
定义和用法:引用计数是跟踪记录每个值被引用的次数。
基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。
工作流程:
-
声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1。
-
同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1.
-
当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1.
-
当引用次数变成0时,说明没办法访问这个值了。
-
当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存。
12.vue生命周期
13.js数组主要有哪些方法?主要参数有哪些?
Array 对象
Array 对象用于在单个的变量中存储多个值。
创建 Array 对象的语法:
new Array();
new Array(size);
new Array(element0, element1, …, elementn);
参数
参数 size 是期望的数组元素个数。返回的数组,length 字段将被设为 size 的值。
参数 element …, elementn 是参数列表。当使用这些参数来调用构造函数 Array() 时,新创建的数组的元素就会被初始化为这些值。它的 length 字段也会被设置为参数的个数。
详细看这里
14.null和undefined的区别?
null
表示没有对象,即该处不应该有值
1) 作为函数的参数,表示该函数的参数不是对象
2) 作为对象原型链的终点
undefined
表示缺少值,即此处应该有值,但没有定义
1)定义了形参,没有传实参,显示undefined
2)对象属性名不存在时,显示undefined
3)函数没有写返回值,即没有写return,拿到的是undefined
4)写了return,但没有赋值,拿到的是undefined
null和undefined转换成number数据类型时
null
默认转成 0
undefined
默认转成 NaN