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 条评论
登录 后参与评论

相关文章

来自专栏用户画像

H5中的标记方法

要使用H5标记,必须先进行如下的doctype声明,不区分大小写。Web浏览器通过判断文件开头有没有这个声明,来判断解析器和渲染类型是否切换到对应的H5模式。

8910
来自专栏Golang语言社区

转--Golang语言-- Web 编程

1.golang的安装工具 1.1 GVM 第三方开发的Go多版本管理工具 2.golang环境变量 2.1 GOROOT=D:\go (golang 安装目录...

36760
来自专栏杨龙飞前端

js中的this关键字,setTimeout(),setInterval()的执行过程

14650
来自专栏大前端_Web

关于Function.prototype.apply.call的一些补充

我们可以看到,ie9的document.getElementById是有Function.prototype上的方法的,所以说,IE9+的宿主对象它们继承了Ob...

21030
来自专栏Laoqi's Linux运维专列

While 循环语句

50490
来自专栏Golang语言社区

转-Go语言开发常见陷阱,你遇到过几个?

Go作为一种简便灵巧的语言,深受开发者的喜爱。但对于初学者来说,要想轻松驾驭它,还得做好细节学习工作。 初学者应该注意的地方: 大括号不能独立成行。 未使用变量...

35790
来自专栏达摩兵的技术空间

与我一起学正则

1、校验密码强度 密码的强度必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间 ^(?=.\d)(?=.[a-z])(?=.*[A-Z])...

8130
来自专栏前端知识分享

第11天:JS中变量、字符串基础知识

js页面效果:轮播图、选项卡、地图、表单验证javascript是弱变量类型的语言,变量只需要用var来声明。而java要根据变 量类型来声明,

43530
来自专栏mySoul

TypeScript入坑

安装插件 https://github.com/Microsoft/TypeScript-Sublime-Plugin

17110
来自专栏测试驿栈

Jmeter(五)_函数

1、它有两个参数,第一个参数是要执行的语句,可以是beanshell语句或者是文件地址,是必选参数;第二个参数是保存结果的变量名称,非必选参数。

21920

扫码关注云+社区

领取腾讯云代金券