题目一数组
var test = function (x) {
var y = new Date();
y = y.getMonth() + x;
return y.toString();
};
console.log(test(3));
console.log(x);
复制代码
答案: 5 报错 x is not function浏览器
解析:此题注意:getMonth()获取到的是0-11 当前月份为3月 getMonth() + 1 = 3; y.getMonth() = 2; x为3,因此第一个结果为5. 第二个由于x没有定义,是形参因此报错。bash
程序题时间数据结构
用js程序输出今天的日期,以YYYY-MM-DD的方式,好比今天2019年1月1日,输出2019-01-01。异步
function getTime(){
var date = new Date();
var y = date.getFullYear();
var m = date.getMonth() + 1;
var d = date.getDate();
function addZero(num){
return num >= 10 ? num : '0'+num;
}
return y + '-' + addZero(m) + '-' + addZero(d);
}
var res = getTime();
console.log(res);
复制代码
js运行机制函数
js主要用途是与用户互动和操做DOM。决定只能是单线程。假若有两个线程,一个线程,一个线程在某个DOM节点添加内容,另外一个线程删除了节点,浏览器应该以哪一个线程为主?ui
单线程意味着全部的任务都须要排队,前一个任务执行完才能执行后面一个任务。 全部的任务分为两种,一种是同步任务(在主线程上排队执行的任务,前面的任务执行完才能执行后面的任务。)另外一种是异步任务(不进入主线程,而进入任务队列的任务。)只有任务队列通知主线程,某个异步任务能够执行了,任务才会进入主线程执行。this
同步任务在主线程上,造成一个执行栈。栈中的代码调用各类外部API,加入各类事件spa
异步任务在任务队列(先进先出的数据结构,排在前面的事件,优先被主线程读取)上线程
任务队列(click,load,回调函数,IO设备事件,还包括鼠标点击,页面滚动等事件)。还能够放置定时事件
只要主线程空了,就会去读取任务队列。这个过程会不断重复。
定时器:定时某些代码多少时间后执行。也就是定时执行的代码。
题目一
var arr = ['第一次输出', '第二次输出', '第三次输出'];
for (var i = 0; i < arr.length; i++) {
setTimeout(function () {
console.log(arr[i]);
//获取数组中下标不存在的数,结果是undefined
}, i * 2000)
}
复制代码
答案:undefined
解析:
for循环在主线程内,setTimeout回调函数是异步方法,在任务队列中,当i=0时,执行循环体代码,setTimeout在任务队列等待。i++, i = 1时,setTimeout在任务队列等待,继续i++,当i=2时,setTimeout在任务队列等待,i++,i = 3时,arr.length为3,不符合条件,循环结束,此时执行延迟的回调函数setTimeout,就会去读取任务队列里的代码。执行任务队列里的代码setTimeout=>此时i为3,arr[3]数组中没有下标为3的,因此打印3次undefined。打印时间分别为0s,1s,2s。
题目2
for (var i = 1; i <= 5; i++) {
setTimeout(function () {
console.log(i);
}, 0);
}
复制代码
答案:5个6
解析:for循环在主线程内,setTimeout回调函数是异步方法,在任务队列中,当for循环结束后才去执行任务队列里的代码。此时有五个setTimeout方法等待在队列中。i为6.因此打印五个6.
题目3
for (var i = 1; i <= 5; i++) {
if (i == 1) {
setTimeout(function () {
console.log(i);
}, 0);
}
};
复制代码
答案: 6
解析:for循环在主线程内,setTimeout回调函数是异步方法,在任务队列中,当for循环结束后才去执行任务队列里的代码。此时主线程有个判断i为1,那么任务队列里只有一个回调函数在等待。for循环结束的时候i为6。因此执行这一个setTimeout输出i为6.
什么是回调函数?
一个函数被做为参数传递给另一个函数。回调函数也叫回调模式。举例:
$("#btn_1").click(function() {
alert("Btn 1 Clicked");
});
复制代码
function() 函数做为参数传递给click方法中
1.定义匿名函数做为回调函数
function getFn(fn){
console.log(111);
}
getFn(function(){
console.log('我是匿名函数');
})
2.定义命名函数,做为参数传递到另外一个函数中
function login(data){
console.log(123);
}
一个接受两个参数的函数,后面一个是回调函数。
function getInfo(options,callback){
callback(options);
}
调用getInfo时,把login做为一个参数传递给它。
getInfo({name:'admin',psw:'123'},login);
复制代码
匿名函数
(function () { var a = b = 1; console.log(a); })()
console.log(a, b);
答案:1 报错
解析: var a = 1; b = 1; a是局部变量,b是全局变量。若是在console.log(a,b)前打印b则为1。而在外面打印a报错
函数声明和函数表达式区别
sum(1,2); //3
function sum(x,y){
alert(x+y);
}
复制代码
ss(1,2); //报错,显示undefined is not a function
var ss = function(x,y){
alert(x+y);
}
复制代码
解析器会率先读取函数声明。而函数表达式,则必须等到解析器执行到它所在的代码行,才会真正的被解析。
深刻理解匿名函数
(function(){
//定义并当即调用
//这是个函数表达式。最后的()表示当即调用这个函数。
})()
复制代码
如下两个都报错
function foo(){ /* code */ }();
function foo(){ /* code */ }( 1 );
复制代码
以上代码要实现,必需要赋值。改为如下两种能够
var aa = function(x){
alert(x);
}(5);//5
复制代码
(function(x){
alert(x);
}(5))
复制代码
自执行函数
即定义和调用合为一体。
(function () { /* code */ } ()); // 推荐使用这个
(function () { /* code */ })(); // 可是这个也是能够用的
复制代码
var i = function () { return 10; } ();
true && function () { /* code */ } ();
0, function () { /* code */ } ();
!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();
// 还有一个状况,使用new关键字,也能够用,但我不肯定它的效率
new function () { /* code */ }
new function () { /* code */ } () // 若是须要传递参数,只须要加上括弧()
复制代码
单独的匿名函数 会报错 没法运行 也没法调用
function(){
return 'lee';
}
复制代码
经过表达式的自我执行
(function(){
alert('lee');
})();
复制代码
把匿名函数赋值给变量
var cat = function(){
return 'lee';
}
alert(cat()); //调用
复制代码
把匿名函数自我执行的返回值赋值给变量
var box = (function(){
return 'lee';
})();
alert(box);
复制代码
自我执行匿名函数的传参
(function(num){
alert(num);
})(100);
复制代码
题目
var test = (function(a) {
this.a = a;
return function(b) {
return this.a + b;
}
} (function(a, b) {
return a;
}(1, 2) ));
console.log(test(4));
复制代码
答案:5
解析:
(function(a, b) {
return a;
}(1, 2) ) => 1
复制代码
var test = (function(a) {
this.a = a;
return function(b) {
return this.a + b;
}
} (1))
test => (function(a) {
this.a = a;
return function(b) {
return this.a + b;
}
} (1))
test() => function(b) {
return this.a + b;
}
test(4) => b = 4; 上面a = 1 ; this.a + b = 5;
匿名函数自调用 this指向的window
复制代码