JS进阶篇(前端面试题整合)(三)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: JS进阶篇(前端面试题整合)(三)

最近刷面试题遇到了一些比较有意思的题目,做个记录(题目均来源于牛客网,解析均是本人的理解,有任何问题欢迎在评论区指出)

Q1:请问以下两次检测对象constructor是否拥有属性名1的结果分别是什么?

1 in Object(1.0).constructor;
Number[1] = 123;
1 in Object(1.0).constructor;

A:false、true

解析:

首先可以认识一下 "in" :用于检查对象(数组)及其原型链中是否含有某键值,如

const arr = [0,2]
1 in arr // true

这里表示的是arr这个数组中存在 1 这个键值,即arr[1]

回归正题:Object(1.0) 相当于 new Number(1.0) ,new Number(1.0).constructor就拿到了Number构造函数,此时Number上还没有 1 这个属性,所以使用 in 返回false,而下一步中增加了这个属性,所以返回true

Q2:下面这段程序的显示结果是?

var x = new Boolean(false);
if (x) {
  alert('hi'); 
}
var y = Boolean(0);
if (y) {
  alert('hello');  
}

A:hi

解析:

Boolean(0)返回一个布尔类型的false
而new Boolean(false)返回一个布尔对象

Q3:以下哪些对象是Javascript内置的可迭代对象?

Array Map String Object

A:Array Map String

解析:

ES6中对可迭代的定义:一种数据结构存在Symbol.iterator属性,就表示可迭代
阮一峰的博客中还提到了以下可迭代的数据类型

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

Q4:以下代码执行后,输出结果为

let x = 10;
let foo = () => {
    console.log(x);
    let x = 20;
    x++;
}
foo();

A:抛出ReferenceError

解析:使用let定义变量会形成 "暂时死区" 即foo作用域内获取的x就是等于20的那个,然而使用let去定义变量,变量不会得到提升,所以在定义前获取x会报错

Q5:请问以下JS代码会输出什么

var a = 10; 
(function a() {
    a = 20;
    console.log(a); 
})()

A:输出函数a的内容

解析: 立即执行函数中的a访问到的是函数a,当函数为IIFE的函数表达式时,与使用const类似(即无法修改这个值),与函数声明( function fun(){} )不相同,当执行a=20时,无法修改a的值

Q6:以下代码执行后,输出结果为

var a = 10;
function a(){}
console.log(typeof a)

A:输出 "number"

解析:我的理解是var会将声明提升到作用域的最高点,function会在js编译时加载在内存中
可以简单理解为:函数声明大于变量声明大于变量赋值,所以原式转换成了下面这段代码

function a(){}
var a;
a = 10;
console.log(typeof a)

验证方式:

console.log(typeof a)// function
var a = 10;
console.log(typeof a)// number
function a(){}
console.log(typeof a)// number

Q7:以下JavaScript代码,在浏览器中运行的结果是

var foo = {n:1};
(function(foo){
    console.log(foo.n);
    foo.n = 3;
    var foo = {n:2};
    console.log(foo.n);
})(foo);
console.log(foo.n);

A:1  2  3

解析:根据var的变量提升,可以得到以下代码;

var foo = {n:1};
(function(foo){
    var foo = foo // 这一步是参数(形参)的声明,赋值
    var foo // 此操作优先级没有参数高,所以不生效
    console.log(foo.n);// 此时foo指代参数,n为1
    foo.n = 3; // 参数引用了全局的foo,所以全局的foo此时已经是3了
    foo = {n:2}; // 给参数重新赋值,相当于指向了一块新内存
    console.log(foo.n); // 打印新内存的值:2
})(foo);
console.log(foo.n);

Q8:请问以下JS代码的输出结果以及变量i的值是?

var i = 100;
function foo() {
    bbb: try {
        console.log("position1");
        return i++;  }
    finally {
        break bbb;
    }
    console.log("position2");
    return i;
}
foo();

A:position1、position2、101

解析:在try中执行return不会打断finally的执行,但是没有打断i++执行,因此执行完try中的语句后,通过break bbb跳出到foo中的bbb级代码块,继续打印下面的position2

Q9:请问以下JS代码输出的结果是什么?

let obj = {
  num1: 117
}
let res = obj;// -----------1
obj.child = obj = { num2: 935 };// -----------2
var x = y = res.child.num2;// ----------3
console.log(obj.child);
console.log(res.num1);
console.log(y);

A:undefined、117、935

解析:这道题主要考察两点:

1.引用类型赋值

2.连续赋值机制

下面我对1-3步做一个分析:

第1步在栈中新建res变量使其引用地址指向obj,即与其共用一个堆地址(这一步可以看做是题目中对第二步的一个伏笔);

第2步是一个连续复制,赋值从右往左看,理解为以下代码,因为在赋值时obj指向了新的堆地址,obj.child中的obj已经不是赋值后的obj了,可以把它暂时看作是res

obj = { num2: 935 };
res.child = obj;

那么此时 res 就是{ child: {num2: 935}, num1: 117 },obj 就是{ num2: 935 };

第3步,连续复制,理解为以下代码

window.y = res.child.num2;
var x = window.y

此时res.child.num2是935,所以x和y都是935

Q10:在浏览器控制台中执行以下代码,输出的结果是

function test() {
    var n = 4399;
    function add(){
        n++;
        console.log(n);
    }
    return {n:n,add:add}
}
var result = test();// ------1
var result2 = test();// ------2
result.add();// ------3
result.add();// ------4
console.log(result.n);// ------5
result2.add();// ------6

A:4400 4401 4399 4400

解析:这道题考察闭包和函数作用域,首先咱得理解的是通过步骤1和2,产生的result和result2是两个不同对象(两个对象指向的堆地址不是一个,虽然内容一样),其次要了解的是test函数和add函数之间产生了闭包关系,所以执行3和4步骤后,n发生了变化,然而值得注意的是,此时的result.n却没有发生变化,这是因为在test函数作用域中,n作为一个基本类型的值随着函数执行完后随着return返回出来了,此时在add中修改的n与result.n已没有关联了。为了更好理解上述说法,我修改了代码,得出以下代码:

function test() {
    var n = {num:4399};
    function add(){
        n.num++;
        console.log(n);
    }
    return {n:n,add:add}
}
var result = test();
var result2 = test();
result.add() // {num: 4400}
result.add() // {num: 4401}
console.log(result.n) // {num: 4401}

这样写应该会有助于理解

言归正传,执行第5步时就是打印最早传入的n(4399),第六步由于上面解析中提到的步骤1和2,产生的result和result2是两个不同对象,所以,可以理解为result2也来了一次步骤3

相关文章
|
10天前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
23天前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
30 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
11天前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
26 4
|
21天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
21天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
29 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
26天前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
39 1
|
27天前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
25 1
|
2月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
142 2
|
2月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
44 0
|
2月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。