js考察的几大核心知识
[TOC]
下面代码的运行结果是什么?作用域
,ES6-let
复制 for ( let i = 0 ;i < 3 ;i ++ ){
setTimeout ( function (){
console .log (i);
} , 0 )
}
for ( var i = 0 ;i < 3 ;i ++ ){
setTimeout ( function (){
console .log (i);
} , 0 )
}
上面代码输出的结果分别是:
原因分析:
let 可以创建词法作用域, 但是var不行. 词法作用域是指作用域是在写代码或者说定义的时候决定的, 而不是在运行的时候决定的. 词法作用域是静态作用域, 而动态作用域是在运行的时候决定的.
扩展问题:
如果还是使用var定义变量,要怎么改写这段代码才能正常运行?闭包
下面代码的运行结果是什么? ES6-let
下面的代码运行中浏览器中
复制 var value = 11 ;
let value2 = 22 ;
window .value = 111 ;
window .value2 = 222 ;
console .log (value);
console .log (value2);
代码输出结果是:
结果分析:
在全局环境中,使用var定义的变量会挂载在全局对象上,浏览器的中全局对象就是window. 所以window修改全局对象的属性会影响到全局变量value的值。
而let定义的变量不会挂载在window全局对象上,所以修改了window.value2的值不会影响到全局变量value2的值。
下面代码的运行结果是什么? this指向
,箭头函数与普通的区别
下面的代码运行在浏览器中
复制 var name = 'global' ;
const obj = {
name : 'xiaoming' ,
sayName : function () {
console .log ( this .name);
} ,
sayName2 : () => {
console .log ( this .name);
}
}
obj .sayName ();
obj .sayName2 ();
回答:
代码输出结果是:
obj.sayName()中 sayName中的this指向的是obj对象本身,所以this.name就是 xiaoming;
obj.sayName2();中由于sayName2使用了箭头函数,箭头函数
此时的this无法判断指向哪里,只有当运行时才知道。可能指向obj,也可能指向window.主要看调用方式,如果是 obj.sayName(),则指向obj,如果是sayName(),则指向window。 但是,如果使用了箭头函数,则this指向window
扩展问题:
下面代码的运行结果是什么?变量提升(var ,funtion)
复制 <! doctype html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport"
content = "width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" >
< meta http-equiv = "X-UA-Compatible" content = "ie=edge" >
< title >Document</ title >
</ head >
< body >
< script >
console .log (fun)
console .log (person , 'person' )
</ script >
< script >
console .log (person)
console .log (fun)
var person = "Eric" ;
function fun () {
console .log (person);
var person = "Tom" ;
console .log (person);
}
fun ();
</ script >
</ body >
</ html >
解答:
复制
< script >
console .log (fun) //fun未定义
console .log (person , 'person' ) // 由于上面报错,所以这行代码不会执行
</ script >
< script >
console .log (person) // undefined,var存在变量提升,所以会报undefind;
console .log (fun) //function,同上
var person = "Eric" ;
function fun () {
console .log (person); // undefined,var存在变量提升,覆盖了外部的person,所以会报undefind;
var person = "Tom" ;
console .log (person); // Tom
}
fun ();
</ script >
扩展题目:
下面代码的运行结果是什么?函数定义的几种方式
变量提升
复制 fn1 ();
console .log (fn2)
console .log (fn3)
function fn1 () {
console .log ( 1 )
}
var fn2 = function () {
console .log ( 2 )
}
const fn3 = function () {
console .log ( 3 )
}
答案:
原因分析:
通过函数申明创建的函数存在变量提升:所以可以直接调用后面定义的函数。所以 fn1()正常执行
使用var定义的变量存在变量提升,但是未运行到代码之前是undefined.运行到后面才会赋值。
使用const定义的变量,不存在变量提升,会存在临时性死区。会报错。
下面代码的运行结果是什么?事件机制
DOM事件级别
复制 <! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< title >Title</ title >
</ head >
< body >
< button onclick = "clickButton()" id = "btn" >button</ button >
< script >
function clickButton(){
console .log ( '事件1' );
}
const btn=document.getElementById('btn');
btn.onclick=function (){
console .log ( '事件2' );
}
btn.addEventListener('click',function (){
console .log ( '事件3' );
})
btn.addEventListener('click',function (){
console .log ( '事件4' );
})
</ script >
</ body >
</ html >
答案:
解析
onclick="clickButton()", btn.onclick都属于DOM0级事件,后面添加的会覆盖前面的。所以只有btn.onclick绑定的事件才生效。只会输出
btn.addEventListener 属于DOM2级别事件,可以重复多个添加,所以都会打印出来
下面代码的运行结果是什么?js事件流
js事件机制
复制 <! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< title >Title</ title >
</ head >
< body >
< table >
< tr >
< td >1</ td >
</ tr >
</ table >
< script >
var table = document .getElementsByTagName ( "table" )[ 0 ];
table . onclick = function (e) {
console .log ( 'table元素' , e . target .nodeName , e . currentTarget .nodeName);
}
var tr = document .getElementsByTagName ( "tr" )[ 0 ];
tr . onclick = function (e) {
console .log ( 'tr元素' , e . target .nodeName , e . currentTarget .nodeName);
}
var td = document .getElementsByTagName ( "td" )[ 0 ];
td . onclick = function (e) {
console .log ( 'td元素' , e . target .nodeName , e . currentTarget .nodeName);
}
</ script >
</ body >
</ html >
答案:
复制 td元素,TD,TD
tr元素,TD,TR
table元素,TD,TABLE
解析:
e.target 和 e.currentTarget的区别:
e.target:它的值是不会变的。因为,它只在事件捕获阶段存在,理解为真实操作的目标元素。
e.currentTarget:它的值会动态变化。它存在事件捕获,事件目标,事件冒泡三个阶段,会随着事件的传播而改变。