01 说明 this 几种不同的使用场景
this
要在执行时才能确认值,定义时无法确认
a. 作为构造函数执行 (this
指向创建出来的实例对象)
function Foo(name) {
this.name = name
}
var f = new Foo('年糕')
b. 作为对象属性执行 (this
指向调用该方法的对象)
var obj = {
name: 'Niangao',
printName: function() {
console.log(this.name)
}
}
obj.printName()
c. 作为普通函数执行 (this
指向window
)
function fn() {
console.log(this)
}
fn()
d. 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 实际开发中闭包的应用
闭包实际应用中主要用于封装变量,收敛权限,下面是一个验证是否为第一次登陆的例子
代码语言:javascript复制function ifFirstLoad() {
var _list = [];
return function (id) {
if(_list.indexOf(id) >= 0) {
return false;
}else {
_list.push(id);
return true;
}
}
}
闭包的使用场景主要有两个:a. 函数作为返回值;b. 函数作为参数传递
代码语言:javascript复制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> 标签,点击的时候弹出对应的序号
代码语言:javascript复制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 如何理解作用域
a. 没有块级作用域,只有函数和全局作用域
b. 自由变量
c. 作用域链,即自由变量的查找
代码语言:javascript复制// 无块级作用域
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 同步和异步的区别是什么
同步会阻塞代码执行,而异步不会
代码语言:javascript复制//异步
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 请求代码示例
代码语言:javascript复制<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>加载示例
代码语言:javascript复制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');
事件绑定示例
07 一道关于 SetTimeout 的题目
代码语言:javascript复制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 如下
代码语言:javascript复制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)
代码语言:javascript复制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 获取随机数,要求是长度一致的字符串格式
代码语言:javascript复制var random = Math.random();
var random = random '0000000000' // 后面加上 10 个零
var random = random.slice(0, 10);
10 写一个能遍历对象和数组的通用 forEach 函数
常用的数组 API 有
API | 作用 |
---|---|
forEach | 遍历所有元素 |
every | 判断所有元素是否都符合条件 |
some | 判断是否有至少一个元素符合条件 |
sort | 排序 |
map | 对元素重新组装,生成新数组 |
filter | 过滤符合条件的元素 |
forEach 遍历所有元素,item
对应的是元素的值,index
对应的是元素的位置
every 用来判断数组所有元素,都满足一个条件
some 用来判断数组所有元素,只要有一个满足条件即可
sort 排序
map 对元素重新组装,生成新数组
filter 通过某一条件过滤数组
代码语言:javascript复制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])
}
}
}