每天五道前端面试题(一)

1.谈谈变量提升

把当前上下文中带有var(变量)/function(函数)进行提升的声明或者定义。变量提升是将变量声明提升到它所在作用域的最开始的部分。

实例一

function a() {
 	console.log(b);
    var b = 'b变量';
}
a();//undefined;

// 这里是因为把函数里面的变量t提升到函数最开始的部分,如下:

 function a(){
     var b;
     console.log(b)
     b='b变量'
}
a()

function(函数)声明会比var(变量)声明优先级更高一点。

  console.log(a) //函数体
  var a = '变量a'
  console.log(a) //变量a
  function a(){
    console.log('函数a')
  }
  console.log(a) // 变量a
  
  //上面的代码把变量/函数提到最开始的地方,注意函数的优先级比变量高,如下:
  
  function a(){
     console.log('函数a')
  }
  var a ;
  console.log(a) //函数体
  a='变量a'
  console.log(a) // 变量a
  console.log(a) // 变量a

js在生成执行环境时,会有两个阶段 。
1.是创建的阶段, JS 解释器会找出需要提升的变量和函数, 并且给他们 提前在内存中开辟好空间, 函数的话会将整个函数存⼊内存中, 变量只声明并且赋值为 undefined
2.代码执行阶段, 我们可以 直接提前使用声明的变量或函数

  • 在提升的过程中,相同的函数会覆盖上⼀个函数,如下
  console.log(a) // 函数A2的函数体
  function a(){
     console.log('函数A1')
  }
  function a(){
     console.log('函数A2')
  }

因为var命令会发生“变量提升”现象,所以ES6中引入了let,它所声明的变量一定要在声明后使用,否则报错

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

2. bind 、call 、apply 区别

  • callapply 都是为了解决改变 this 的指向 。作用都是相同的, 只是传参的方式
    不同。
  • 除了第⼀个参数外, call 可以接收⼀个参数列表, apply 只接受⼀个参数数组
let a = {
    value:1
 }
function getValue(name,age){
    console.log(name)  // 小土豆
    console.log(age) // 18
    console.log(this.value) // undefined
 }
 getValue('小土豆',18)
 
// 上面例子中,this.value为undefined 我们想访问a中的value,就用call,apply如下:

 let a = {
     value:'call'
 }
 let b = {
     value:'aplly'
 }
 function getValue(name,age){
     console.log(name)  // 小土豆call  小土豆aplly
     console.log(age) // 9 10
     console.log(this.value)  //call applly
 }
 getValue.call(a,'小土豆call',9)  //可以接收⼀个参数列表
 getValue.apply(b,['小土豆aplly',10]) // 只接受⼀个参数数组

bind 和其他两个方法作用也是⼀致的, 只是该方法会返回⼀个函数 。并且我
们可以通过 bind 实现柯里化

let a = {
     value: 'bind'
}
function getValue(name, age) {
    console.log(name)  // 小土豆bind
    console.log(age) // 28
    console.log(this.value)  //bind
}
let whatbind = getValue.bind(a, '小土豆bind', 28)
// bind返回的是一个函数
 whatbind()

3.如何实现⼀个bind,call ,apply 函数

对于实现bind函数, 可以从⼏个方面思考
1. 不传⼊第⼀个参数,那么默认为 window
2. 改变了 this 指向,让新的对象可以执行该函数 。那么思路是否可以变成给新的对象添加
⼀个函数,然后在执行完以后删除?

实现bind函数

// 2.定义我们的myBind
Function.prototype.myBind = function (context) {
   // 3.检查this
   // 这里的函数为getValue调用所以this指向getValue函数
   if (typeof this !== 'function') {
          throw new TypeError('Error')
   }
   var _this = this
   // 4.删除第一个参数 a 
    let args = [...arguments].slice(1)
   // 5.bind函数会返回一个函数 所以我们这儿也返回一个函数
    return function A() {
        // 因为这里return了个函数所以 这里的函数为 whatbind所调用 this指向 Window  
        // 判断
         if (this instanceof A) {
           	return new _this(...args, ...arguments)
          }
          // 把getValue的this指向第一个参数 同时跟参数return出去
         return _this.apply(context, args.concat(...arguments))
    }
 }

// 1假设我们写好了自己的bind函数命名为myBind 跟 bind的用法保持一致
 let a = {
     value: 'bind函数'
 }
function getValue(name, age) {
       console.log(name);
       console.log(age);
       console.log(this.value);
 }
let whatbind = getValue.myBind(a, '我是bind', '20min')
// 6.定义的bind返回函数所以我们得调用
whatbind(

实现call函数

Function.prototype.myCall = function (context) {
    var context = context || window
    // 给 context 添加⼀个属性
    // getValue.call(a, '我是call', '20min') => a.fn = getValue
    context.fn = this
    // 将 context 后面的参数取出来
    var args = [...arguments].slice(1)
    // getValue.call(a, '我是call', '20min') => a.fn('我是call', '20min')
    var result = context.fn(...args)
    //删除 fn
     delete context.fn
     return result
}
let a = {
    value: "call函数"
}
function getValue(name, age) {
    console.log(name);
    console.log(age);
    console.log(this.value);
}
getValue.myCall(a, '我是call', '20min')

实现apply函数

Function.prototype.myApply = function (context) {
    var context = context || window
    context.fn = this
    var result
    // 需要判断是否存在第二个参数
    // 如果存在,就将第二个参数展开
    if (arguments[1]) {
         result = context.fn(...arguments[1])
    } else {
      	 result = context.fn()
    }
        delete context.fn
        return result
    }
let a = {
    value: "apply函数"
}
function getValue(name, age) {
     console.log(name);
     console.log(age);
     console.log(this.value);
}
getValue.myApply(a, ['我是apply', '20min'])
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我无法提供具体的2024年端面试题一百道,因为面试题的内容和形式可能会因公司、职位和行业而异。不过,我可以提供一些通用的端面试题,以帮助您准备面试。 1. 请简述端开发的主要技术栈包括哪些? 2. 请描述一下什么是HTML、CSS和JavaScript? 3. 请解释一下什么是响应式设计?如何在端开发中实现响应式设计? 4. 请简述一下什么是端框架,并列举几个常用的端框架。 5. 请解释一下什么是Vue.js,并简述其核心概念和用法。 6. 请解释一下什么是React.js,并简述其核心概念和用法。 7. 请简述一下什么是Webpack,并解释其作用和用法。 8. 请解释一下什么是ES6,并列举一些ES6的新特性。 9. 请简述一下什么是端性能优化,并列举一些优化技巧。 10. 请解释一下什么是HTTP/2,并简述其优点和缺点。 除了以上问题,您还可以准备一些更具体的问题,例如: 1. 请解释一下如何使用CSS选择器选择元素? 2. 请解释一下如何使用JavaScript操作DOM? 3. 请描述一下如何使用Vue.js实现一个简单的计数器组件。 4. 请解释一下如何使用React.js实现一个简单的表单组件。 5. 请描述一下如何使用Webpack进行代码拆分和优化。 6. 请解释一下什么是跨域问题,并简述如何解决跨域问题。 7. 请描述一下如何使用JavaScript进行异步编程,例如使用Promise和async/await。 8. 请解释一下什么是端安全,并列举一些常见的安全问题及其解决方法。 希望以上信息对您有所帮助,祝面试成功!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值