首页 > 试题广场 >

以下代码执行时不会在控制台输出错误信息的是:

[单选题]
以下代码执行时不会在控制台输出错误信息的是:
  • let a = decodeURIComponent('%');
  • var a;
    a();
    function a() {
      console.log(a);
    }
  • Promise.reject(123).finally(a => {
      console.log(a);
    });
  • var a = 1;
    let a = 2;
    console.log(a);
● 首先, js有变量提升和函数提升,指的是用 var声明变量 或用 function 函数名(){  } 声明的,会在 js预解析 阶段提升到顶端;(es6的let  和 const 不会提升)
其次,函数提升优先级 高于 变量提升
注意, 相同作用域时声明变量而不赋值则还是以前的值, 而子作用域声明不赋值则函数内该值为undefined,因为声明了私有变量

让我们看看下面的代码
console.log(foo); 
var foo = 1  //变量提升
console.log(foo)
foo()
function foo(){ //函数提升
   console.log('函数')
}
等价于
function foo(){ //提到顶端
   console.log('函数')
}
var foo  
console.log(foo) //输出foo这个函数,因为上面foo没有被赋值,foo还是原来的值 
foo = 1;  //赋值不会提升,赋值后 foo就不再是函数类型了,而是number类型
console.log(foo) //输出1
foo() //这里会报错,因为foo不是函数了
理解了以上, 基本就没有问题了

编辑于 2019-09-11 02:08:29 回复(11)
A."URIError: malformed URI sequence"
发表于 2020-03-15 09:58:13 回复(0)

A 选项主要是 URI 编码,主要是对特殊字符进行转义,具体规则可以查阅相关资料

其实可以简单理解成转义,类似于在字符串中输出\需要写成\\一样,%在这里就是一个转义字符。只有转义字符的开头却没有要被转义的东西,肯定是会报错的。

B 选项主要是变量提升,并且函数优先于变量进行提升。其他人已经说得很好了。

C 选项需要 catch 被 reject 的 Promise,才能不抛出错误。这里的错误类似于执行了一个会抛出异常的操作,但却没有捕获。这是一种可以正常运行的写法:

Promise
    .reject(123)
    .catch(err => console.log(err))
    .finally(a => console.log(a));

D 选项因为 let 的 TDZ(“暂时性死区”),在 let 的作用域中无法重复声明,也无法在声明语句之前使用(没有变量提升)。简而言之,在 let 语句出现之前,都是无法使用该变量的。

补充一点。这种情况下是可以正常运行的:

var a = 1;
{
    let a = 2;   
}
console.log(a);
编辑于 2020-09-25 15:07:45 回复(0)
B选项:主要考察的是函数的提升和变量的提升,牢记一点:函数提升后的位置在变量提升后的位置之后,也就是相当于先声明一个var a,然后function a()函数提升了,将其覆盖,所以B选项无论在哪个位置打印a,输出的都是a这个函数
A选项:decodeURIComponent()里面的参数:必需。一个字符串,含有编码 URI 组件或其他要解码的文本。我没用过,可以直接参考w3c:https://www.w3school.com.cn/jsref/jsref_decodeURIComponent.asp
D选项:可以直接看看let 和 var的区别  两个都是var的话下面会直接覆盖上面的,let的话重复定义会报错。

编辑于 2019-08-24 09:57:40 回复(8)
A选项:
let a = decodeURIComponent('%');  参数应该是一个字符串,含有编码 URI 组件或其他要解码的文本。正确用法如下:先编码,再解码
var test1="http://www.w3school.com.cn/My first/";
document.write(encodeURIComponent(test1)+ "<br />")
document.write(decodeURIComponent(test1))
B选项:正确
变量提升后的顺序为:
function a() {
console.log(a); //不会输出undefined,而是直接打印这个函数
}
var a;  //声明变量不赋值,会保持原有值不变
a(); //正常调用函数

D选项:
两个都是var的话下面会直接覆盖上面的,let的话重复定义会报错
求大佬解释C选项!!!
发表于 2020-05-09 16:23:32 回复(3)
关于C的个人理解,MDN解释:Promise.prototype.finally(onFinally)添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)。Promise.reject直接就是出错了,后边的finally只是无论前面的promise是否出错都会走的一个新的promise,相当于错误没有处理,那么在控制台上报错了,如果代码改成Promise.reject(123).catch((a)=>{console.log(a)}),或者在finally后面再加一个catch对错误进行手动处理,控制台就不会报错了。有更合理的解释欢迎探讨。
发表于 2019-10-10 14:38:22 回复(0)
变量提升,函数提升只是一种形象为了易懂的技巧。js中并没有什么变量提升,函数提升。要解释这种类型的题应该用上下文的词法环境,执行上下文来解释,每个执行上下文对应一个独立的词法环境。注册表中变量名可以函数名被覆盖,函数名不能被变量名覆盖。具体可以参考javascript忍者秘籍。
发表于 2019-08-30 10:01:13 回复(0)
Promise.reject(123).finally () 无论是否错误 都会执行最后一条语句 且 Promise.reject() 即会发出一条错误
Promise.reject(123).then(function(){
},function(error){
  console.error(error)
} )
发表于 2020-03-13 21:19:44 回复(0)
对于答案 B:  
因为答案里面的 a 是未赋值的,所以后面的函数提升可以覆盖变量a。如果a已经有确定的值就会这样:
var a = 3;
a(); // a is not a function
function a() {
console.log(a);
}
在JavaScript中,当一般变量、函数、函数参数重名时,它们的优先级为:
已初始化的一般变量 > 函数 > 函数参数 > 未初始化的一般变量

发表于 2021-09-06 23:47:01 回复(0)
上面的B选项存在了变量提升的情况,所以等价于
function a() {
console.log(a);
}
var a;
a();  

函数 a 覆盖了原来的变量a所以不会报错,最后的结果是输出了    a    这个函数
编辑于 2020-11-17 15:10:09 回复(2)
C选项由于无法知道promise的最终状态,所以finally的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。
发表于 2020-05-27 17:26:12 回复(0)
Promise.reject(123).finally(a => {
  console.log(a);
});
finally是没有入参的
发表于 2022-02-19 12:52:27 回复(0)
 
A选项,decodeURIComponent() 函数,作用是对 URI 组件进行解码。浏览器在对“%”执行decodeURIComponent时报错,正确的解决是将%全部替换为%25再进行传输
B选项,由于 函数提升 比 变量提升 优先级高,编译时,函数声明会放在前面,顺序为
function a() {
    console.log(a);
}
var a;
a();
但使用 var 声明变量时未进行初始化,读取a时函数的优先级高一些,最终的输出结果为:

如果var 声明并进行初始化,a就会变成变量,代码就会报错,如图
var a = '2';
a();
function a() {
    console.log(a);
}

C选项, Promise 的 finally方法,由于无法知道 promise 的最终状态,所以 finally 的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。其中 a 未定义。

D选项,let 不能重复声明,var可以重复声明



发表于 2022-10-15 16:58:16 回复(0)
function foo(){           //函数提升
    console.log('函数')
}
var foo                       //变量提升
console.log(foo)      //函数提升优先级高 foo=[Function: foo]
foo = 1
console.log(foo)      //foo被赋值为 1 foo=1
foo()                         //报错 foo此时不是函数了,而是number型1
变量和函数提升,其余代码位置不变

发表于 2021-10-15 20:37:23 回复(1)
声明相同的变量但不赋值,是不会覆盖的。
发表于 2019-09-22 13:42:54 回复(0)
在控制台输出的确只有B没有报错,,,但不是很清楚为什么,等大佬解惑🤣
编辑于 2019-08-15 15:29:25 回复(2)
选项A :decodeURIComponent()方法用来解码 encodeURIComponent()方法或者其他类似方法编码的URI传入的参数需要是编码后的 URI否则报URIError: malformed URI sequence  ‘%’转为URI为“%25” 所以A会报错

发表于 2023-10-05 20:31:20 回复(0)
同名的函数声明优先级高于同名的变量声明 因为后面的var只有定义没有赋值 因此保留着原来的状态 b选项promise抛出错误要用catch接住才不会报错
编辑于 2023-05-07 01:25:26 回复(0)
B选项,存在变量提升和函数提升且a函数声明先于 a 变量声明,但是在 a 变量声明时未赋值,此时的 a 相当于是一个函数。在 a 赋值前,执行 a() 不会报错,除非 执行a函数是在 a 赋值了一个值之后,使得 a 不再是一个函数。

C 选项,Promise.reject(123) 会抛出一个异常,如果没有 catch 或者再 then 中接住进行异常处理,就会直接报错。
编辑于 2023-02-19 11:38:34 回复(0)
变量与函数重名,不应该是变量生效吗
发表于 2022-10-27 21:35:27 回复(0)