专栏首页Nian糕的私人厨房JavaScript 常见面试题分析(二)

JavaScript 常见面试题分析(二)

Unsplash

01 说明 this 几种不同的使用场景

this 要在执行时才能确认值,定义时无法确认

运行结果

① 作为构造函数执行 (this 指向创建出来的实例对象)

function Foo(name) {
    this.name = name
}
var f = new Foo('年糕')

运行结果

② 作为对象属性执行 (this 指向调用该方法的对象)

var obj = {
    name: 'Niangao',
    printName: function() {
        console.log(this.name)
    }
}
obj.printName()

运行结果

③ 作为普通函数执行 (this 指向 window)

function fn() {
    console.log(this)
}
fn()

运行结果

call() 方法 apply() 方法 bind() 方法 (this 指向第一个参数)

function fn1(name, age) {
    console.log(name)
    console.log(this)
}
fn1.call({x:100}, 'niangao', 17)

function fn2(name, age) {
    console.log(name)
    console.log(this)
}
fn2.apply({x:100}, ['niangao', 17])

var fn3 = function(name){
    console.log(name)
    console.log(this)
}.bind({y:200})
fn3('niangao')

运行结果

02 实际开发中闭包的应用

闭包实际应用中主要用于封装变量,收敛权限,下面是一个验证是否为第一次登陆的例子

function ifFirstLoad() {
    var _list = [];
    return function (id) {
        if(_list.indexOf(id) >= 0) {
            return false;
        }else {
            _list.push(id);
            return true;
        }
    }
}

运行结果

闭包的使用场景主要有两个:① 函数作为返回值;② 函数作为参数传递

function F1() {
    var a = 100;
    // 函数作为返回值
    return function(){
        console.log(a)
    }
}
var f1 = F1();

function F2(fn) {
    var a = 200;
    // 函数作为参数传递
    fn()
}
F2(f1)

03 创建 10 个 <a> 标签,点击的时候弹出对应的序号

for(var i = 0; i < 10; i++){
    (function(i){
        var div = document.createElement('div');
        div.innerHTML = i + '<br>';
        div.addEventListener('click', function(e){
            e.preventDefault();
            console.log(i);
        })
        document.body.appendChild(div)
    })(i)
}

运行结果

04 如何理解作用域

① 没有块级作用域,只有函数和全局作用域 ② 自由变量 ③ 作用域链,即自由变量的查找

// 无块级作用域
if(true){
    var name = "niangao"
}
console.log(name) // niangao

// 函数和全局作用域
var a = 100;
function fn() {
    var a = 200;
    console.log('fn', a);
}
console.log('global', a) // global 100
fn() // fn 200

a 和 b 是自由变量——当前作用域没有定义的变量,即“自由变量”

运行结果

上面这个例子中,console.log(a); 并没有在当前作用域寻找到自由变量 a,于是不断的往父级作用域寻找自由变量 a,直到全局作用域,而能够沿着作用域一级级向上寻找的机制就称为“作用域链”

需要注意的是,一个函数的父级作用域是它定义时的作用域,而不是它执行时的作用域

运行结果

05 同步和异步的区别是什么

同步会阻塞代码执行,而异步不会

//异步
console.log(100);
setTimeout(function(){
    console.log(200);
}, 1000)
console.log(300);

//同步
console.log(100);
alert(200);
console.log(300);

06 前端使用异步的场景有哪些

在可能发生等待的情况下,我们会需要异步,比如定时任务(setTimeout, setInterval),网络请求(Ajax 请求,动态 <img> 加载),事件绑定

Ajax 请求代码示例

<script src="./jquery.js"></script>
<script type="text/javascript">
    console.log('start');
    $.get('./data.json', function(data) {
        console.log(data);
    })
    console.log('end');
</script>

运行结果

<img>加载示例

console.log('start');
var img = document.createElement('img');
img.onload = function(){
    console.log('loaded')
}
img.src = 'https://github.com/Niangao-Warren/JianShu/blob/master/Demo/Mouse_sliding_picture_showing_hidden/images/n1.jpg?raw=true';
console.log('end');

运行结果

事件绑定示例

运行结果 1

运行结果 2

07 一道关于 SetTimeout 的题目

console.log(1);
setTimeout(function(){
    console.log(2)
}, 0);
console.log(3);
setTimeout(function(){
    console.log(4)
}, 1000);
console.log(5);

运行结果

08 获取 2018-02-07 格式的日期

常用的日期 API 如下

Date.now() // 获取当前时间毫秒数
var today = new Date()
today.getTime() // 获取毫秒数
today.getFullYear() // 年
today.getMonth() // 月(0-11)
toddy.getDate() // 日(0-31)
today.getHours() // 时(0-23)
today.getMinutes() // 分(0-59)
today.getSeconds() // 秒(0-59)
function formatDate(today) {
    if(!today) {
        today = new Date()
    }
    var year  = today.getFullYear(),
        month = today.getMonth() + 1,
        date  = today.getDate();
    if(month < 10) {
        month = '0' + month;
    }
    if(date < 10) {
        date = '0' + date;
    }
    return year + '-' + month + '-' + date;
}

运行结果

09 获取随机数,要求是长度一致的字符串格式

var random = Math.random();
var random = random + '0000000000' // 后面加上 10 个零
var random = random.slice(0, 10);

image.png

10 写一个能遍历对象和数组的通用 forEach 函数

常用的数组 API 有

API

作用

forEach

遍历所有元素

every

判断所有元素是否都符合条件

some

判断是否有至少一个元素符合条件

sort

排序

map

对元素重新组装,生成新数组

filter

过滤符合条件的元素

forEach 遍历所有元素 item 对应的是元素的值,index 对应的是元素的位置

forEach

every 用来判断数组所有元素,都满足一个条件

every

some 用来判断数组所有元素,只要有一个满足条件即可

some

sort 排序

sort

map 对元素重新组装,生成新数组

map

filter 通过某一条件过滤数组

filter

function forEach(obj, fn) {
    var key;
    if(obj instanceof Array) {
        obj.forEach(function(item, index) {
            fn(index, item)
        })
    }else {
        for(key in obj) {
            fn(key, obj[key])
        }
    }
}

运行结果

End of File

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JavaScript Console的常见用法

    行文过程中出现错误或不妥之处在所难免,希望大家能够给予指正,以免误导更多人,最后,如果你觉得我的文章写的还不错,希望能够点一下喜欢和关注,为了我能早日成为简书优...

    Nian糕
  • Vue2.0 歌手数据获取及排序

    本次的系列博文的知识点讲解和代码,主要是来自于 黄轶 在慕课网的 Vue 2.0 高级实战-开发移动端音乐WebApp 课程,由个人总结并编写,其代码及知识点...

    Nian糕
  • JavaScript 去除字符串首尾空格

    Nian糕
  • JavaScript几个作用域问题

    1、 var a = 0 ; function f(){ a = 1; console.log(a); //全局变量a } console.log(a...

    寒月十八
  • 《你不知道的js(上卷)》笔记1(基础知识和闭包)

    首先,读本书让我了解到js的最重要的两个知识点——闭包还有this指向,其次一点的就是编译原理和对象原形。

    陨石坠灭
  • (建议收藏)原生JS灵魂之问, 请问你能接得住几个?(上)

    笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过。打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有...

    桃翁
  • 原生JS的知识系统梳理

    笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过。打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有...

    前端迷
  • 原生JS灵魂考核, 你能回答出来几题?

    笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过。打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有...

    Nealyang
  • 前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例

    使用vue-cli可以规范项目,提高开发效率,但是使用vue-cli时需要一些ECMAScript6的知识,特别是ES6中的模块管理内容,本章先介绍ES6中的基...

    张果
  • 前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例

    使用vue-cli可以规范项目,提高开发效率,但是使用vue-cli时需要一些ECMAScript6的知识,特别是ES6中的模块管理内容,本章先介绍ES6中的基...

    张果

扫码关注云+社区

领取腾讯云代金券