博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js时间+函数+匿名函数,...
阅读量:6419 次
发布时间:2019-06-23

本文共 4441 字,大约阅读时间需要 14 分钟。

题目一

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没有定义,是形参所以报错。

程序题时间

用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节点添加内容,另一个线程删除了节点,浏览器应该以哪个线程为主?

单线程意味着所有的任务都需要排队,前一个任务执行完才能执行后面一个任务。 所有的任务分为两种,一种是同步任务(在主线程上排队执行的任务,前面的任务执行完才能执行后面的任务。)另一种是异步任务(不进入主线程,而进入任务队列的任务。)只有任务队列通知主线程,某个异步任务可以执行了,任务才会进入主线程执行。

同步任务在主线程上,形成一个执行栈。栈中的代码调用各种外部API,加入各种事件

异步任务在任务队列(先进先出的数据结构,排在前面的事件,优先被主线程读取)上

任务队列(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复制代码

转载地址:http://zqvra.baihongyu.com/

你可能感兴趣的文章
站长怎样理性选择虚拟主机
查看>>
linux文件系统\环境变量\帮助文件
查看>>
ioS开发知识(二十二)
查看>>
svn 配置
查看>>
安装saltstack遇到缺包问题!自己遇到的错!若有雷同请海涵
查看>>
数学基础知识03——坐标系变换
查看>>
理解 HashMap 加载因子 loadFactor
查看>>
第三周编程总结
查看>>
发布功能完成
查看>>
用js实现返回上一页
查看>>
因数分解
查看>>
数据结构之队列
查看>>
并发编程(二)
查看>>
[html5]localStorage的原理和HTML5本地存储安全性
查看>>
vc 多行文本框CEdit垂直滚动条定位到最底端
查看>>
basic4android 开发 推送功能
查看>>
centos7安装redis
查看>>
EF 约定介绍
查看>>
web 服务发布注意事项
查看>>
http缓存详解
查看>>