当前位置: 首页 > news >正文

当SetTimeout遇到了字符串

今天闲来没事的时候,去逛逛segementFault,看了看别人提的问题。说到setTimeout和window.onload冲突。一开始我是挺疑惑他表他什么意思的,因为setTimeout和window.onload应该不会有明显的冲突吧。带着疑惑去追问。后来贴出代码的时候我就明白了,来看看他的代码中的疑惑吧。

window.onload=function(){
setTimeout("D.style.background='#990033'",2000);
}

他觉得这个代码运行的时候,setTimeout会报错,不能正确的运行指定的代码,就觉得在window.onload和setTimeout有冲突。

我对这个问题非常感兴趣。也自己试了一下,发现确实不能运行字符串里面的代码。但是还是很怀疑window.onload和setTimeout怎么可能会有冲突呢?

解决问题

为了测试方便,我就稍微改动了一下代码。将setTimeout的调用改成调用函数。

window.onload = function() {
    function myFun(i) {
        alert(1);
    }
    setTimeout('myFun(1)', 2000);
}

在这里发现的确不能运行,但是这里的问题就很明显了,我将函数的调用变成了 'myFun(1)' 字符串调用,所以会出现不能调用 myFun() 的问题。

为了深入理解我们在W3school查询一下setTimeout的用法。

那么就是setTimeout只能接受函数或者是表达式的计算。那么现在答案很明显了,既是setTimeout不支持第一个参数为字符串的调用。

但是按照提问者的用法,这种 "D.style.background='#990033'" CSS的调用也必须准守这种形式那么怎么办?

那么就服从setTimeout的规则,说干就干,将他装换成函数就好了。见以下代码。

window.onload=function(){
setTimeout(function(){
    D.style.background='#990033'
},2000);
}

这里的2秒钟之后就会执行setTimeout里面的匿名函数,即准守了setTimeout的原则,也可以利用setTimeout来调用类似字符串的形式的功能代码。

回到提问并且深入挖掘

回到提出的问题上来,深入的挖掘,其实并不是setTimeout和window.onload有冲突,在原来的问题中,其实是Javascript作用域在作怪。

在原先的问题中,如果是 setTimeout("D.style.background='#990033'",2000); 的话,由于setTimeout的第一个参数支持的是函数或者是表达式,所以字符串会被自动执行 new Function ,将这个字符串强制转换成一个函数。

我们知道在Javascript中,函数里面有自己的作用域,和外界的作用域不同,而在函数内部并没有D.style.background这个对象,所以会有报错。在我变化的例子中,也是如此,如果使用了 setTimeout('myFun(1)', 2000),那么这里面的字符串就会被自动执行 new Function ,所以创建出来的函数不在这个作用域内,当然也就不能调用,会出现无法找到的问题了。

相关文章:

  • ABP文档 - EntityFramework 集成
  • [Java基础] Java中List.remove报错UnsupportedOperationException
  • 查看linux服务器的系统信息
  • sql事务、视图和索引
  • 谈谈springmvc的ResponseBodyAdvice
  • C语言之从内存角度理解不同类型的变量
  • Android 利用线程运行栈StackTraceElement设计Android日志模块
  • .Net中ListT 泛型转成DataTable、DataSet
  • linux线程的实现【转】
  • JAVA设计模式
  • 你知道市面上机器人都用哪些操作系统吗【转】
  • ArcGIS安装错误1402
  • 前端的学习
  • .NET 表达式计算:Expression Evaluator
  • 2016-11-10试题解题报告
  • 分享一款快速APP功能测试工具
  • C++类的相互关联
  • C++入门教程(10):for 语句
  • gcc介绍及安装
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • JAVA并发编程--1.基础概念
  • java第三方包学习之lombok
  • Js基础知识(一) - 变量
  • MySQL主从复制读写分离及奇怪的问题
  • PAT A1017 优先队列
  • PHP CLI应用的调试原理
  • PHP那些事儿
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • SQLServer之创建显式事务
  • 从PHP迁移至Golang - 基础篇
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 用mpvue开发微信小程序
  • 自制字幕遮挡器
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • Mac 上flink的安装与启动
  • 进程与线程(三)——进程/线程间通信
  • ​​​​​​​​​​​​​​Γ函数
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • # 达梦数据库知识点
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)springboot教学评价 毕业设计 641310
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转)mysql使用Navicat 导出和导入数据库
  • (转)ObjectiveC 深浅拷贝学习
  • (转)创业的注意事项
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转)项目管理杂谈-我所期望的新人
  • . Flume面试题
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .bat批处理(十一):替换字符串中包含百分号%的子串