阿里巴巴js面试题1

本文深入探讨JavaScript中预处理机制、变量与函数提升的概念,通过具体实例解释这些特性如何影响代码执行流程。

转载自http://blog.youkuaiyun.com/qq_27682041/article/details/76473068

该题难度系数: ★★★

考查的技术点:  1). 变量提升 2). 函数提升  3). 预处理  4). 调用顺序

[php] view plain copy
  1. var c = 1;  
  2. function c(c) {  
  3.     console.log(c);  
  4.     var c = 3;  
  5. }  
  6. c(2);  


运行结果:



看到这结果有没有大吃一惊?

我们现在来分析下原因。

这里我们先来了解下“预处理”,那什么是预处理呢?js语言本身具有预处理机制,js引擎在预处理期对所有声明的变量和函数进行处理,就是先把变量进行声明并读到内存里。也就是收集用var声明的变量信息和函数声明信息

还有一点是预处理时,变量和函数的优先顺序,先变量后函数。当变量名和函数名一致时后者会覆盖前者,我们看下下面的小案例,

[javascript] view plain copy
  1. function b() {  
  2. }  
  3. var b  
  4. console.log(typeof b)  

结果为function,这就证实了,我们刚才的结论,执行顺序先变量后函数,变量名一致时,函数就会覆盖变量。

再来说一下预处理,看一下下面的小案例:

[javascript] view plain copy
  1. var a = 2    
  2. function fn() {    
  3.     console.log(a)    
  4.     var a = 3    
  5. }    
  6. fn()  


运行下,结果为undefined。

为什么为undefined呢?因为这里预处理顺序是这样的,外面声明了个全局变量a,值为2,但是里面把a声明成了局部变量,函数内部的预处理顺序为先声明var a;然后console.log(a);最后a=3;所以我们调用函数的时候,里面是有a,所以不会调外面的全局a,只是里面的a暂时还没有值,因为a=3这赋值步骤是在console.log(a)后面执行的,所以我们运行时就看到undefined了。拓展下,如果函数里面去掉var,那么打印出来的值就是2了,然后全局变量a又被赋值为3。

那好,我们现在回到我们刚才的题目上来,刚才题目的解析顺序可以理解为以下步骤:

先预处理var c;

然后预处理整个c函数

function c(c) {
            console.log(c)
            var c = 3
    }

此时c的typeof为function

接下来再给c赋值,值为1,即c=1,此时c是整型变量1.typeof为number了。

最后再执行c(2)调用函数。所以我们调用的时候当然就会报c不是一个函数的错误了,因为他现在是一个整型变量了啊,哈哈,是不是很伤脑筋啊……

最后我们再次运行以下代码,证实我们的结论:

[javascript] view plain copy
  1. var c = 1  
  2. function c(c) {  
  3.     console.log(c)  
  4.     var c = 3  
  5. }  
  6. console.log(c) //   
  7. console.log(typeof c) //   
  8. c(2) //  

结果截图:


再唠叨下,这题里面给我们设了陷阱,全局变量名、函数名、函数形参都是c,这是面试官为了迷惑我们的,考查我们的相关知识是否理解得透彻,分析是否仔细了。毕竟是名企面试题,很注重考查基础的……


### 阿里巴巴前端开发职位面试题解析 阿里巴巴作为中国领先的互联网公司之一,其前端开发职位的面试通常涵盖多个技术领域,包括基础知识、框架理解、性能优化以及问题解决能力等。以下是一些高频面试题及其解析,结合了过往的面试经验与技术考察点。 #### 1. React 组件模型的理解 React 有两种主要的组件模型:类组件(Class Component)和函数组件(Function Component),它们在实现方式和使用场景上各有不同。 - 类组件基于 `class` 语法,需要继承 `React.Component`,并使用 `this.state` 和 `setState` 来管理状态,生命周期方法如 `componentDidMount` 也需显式定义。 - 函数组件则更加简洁,依赖于 `useState`、`useReducer` 等 Hook 来管理状态,通过 `useEffect` 模拟生命周期逻辑,支持自动优化,性能更轻量[^3]。 #### 2. 闭包的概念及其潜在问题 闭包是指函数嵌套函数时,内部函数引用了外部函数的变量,从而导致垃圾回收机制无法回收这些变量。这种机制虽然可以实现数据封装和私有变量,但也可能带来内存泄漏问题,影响项目性能[^4]。 ```javascript var myObject = { foo: "bar", func: function () { var self = this; console.log(this.foo); // bar console.log(self.foo); // bar (function () { console.log(this.foo); // undefined(this 指向全局对象) console.log(self.foo); // bar })(); }, }; myObject.func(); ``` 上述代码中,自执行函数内部的 `this` 指向全局对象,因此 `this.foo` 是 `undefined`,而 `self.foo` 依然可以访问到外部作用域的 `foo`。 #### 3. TCP 与 UDP 的使用场景 - **TCP** 适用于对准确性要求高但对效率要求相对较低的场景,例如文件传输、邮件接收、远程登录等。TCP 通过确认、重发、排序等机制确保数据的完整性和正确性。 - **UDP** 则适用于对效率要求高而对准确性要求相对较低的场景,例如即时通讯、在线视频、网络语音电话等。UDP 不进行数据确认和重发,因此速度更快,适合实时性要求高的应用[^4]。 #### 4. 异步编程中的 `async/await` 行为 在 `async/await` 中,如果 `await` 后面的 `Promise` 处于 `pending` 状态,则后续代码不会执行,包括 `.then()` 等链式调用。这要求开发者在处理异步逻辑时,必须确保 `Promise` 能够正确地 `resolve` 或 `reject`,以避免程序阻塞。 #### 5. 前端性能优化策略 阿里巴巴前端面试中经常考察性能优化方面的知识,包括但不限于: - **资源加载优化**:使用懒加载、预加载、CDN 加速等手段减少首屏加载时间。 - **代码拆分**:通过 Webpack 等工具进行代码分割,按需加载模块。 - **缓存策略**:合理设置 HTTP 缓存头,利用浏览器缓存减少重复请求。 - **减少重绘重排**:避免频繁操作 DOM,使用虚拟 DOM 或批处理更新。 - **图片优化**:使用 WebP 格式、响应式图片、压缩图片大小等。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值