你自认为理解了JavaScript?
关于Dmitry Baranovskiy 的博客中一篇文章(http://dmitry.baranovskiy.com/post/91403200),其中有五段小代码,用来测试是否理解 JavaScript 的核心,闭包和作用域, 该文章也在csdn论坛上受到过关注和讨论, 集思广益,下面结合自己的理解,做了如下小结。
1
if (!("a" in window)) {
var a = ;
}
console.log(a);
程序会首先解析所有声明的函数,其次是var声明的变量,因为javascript没有块的概念,所以if(){...}中,var声明了 a = 1, a是依然属于全局变量。
执行等价于:
var a; //全局
if (!("a" in window)) {
a = ;
}
console.log (a);
(1)开始时,声明了变量a,但并没有赋值,所以a = undefined , 而undefined 存在于window中,所以(’a’ in window)返回true, 取反为false, 这样就不会执行大括号里面的 “a=1” 的语句。
(2) console.log(a); //undefined
2
var a = ,
b = function a (x) {
x && a (--x);
};
console.log (a);
可以用一个var,来声明多个变量,中间用多个逗号分开,执行等价于:
var a = ;
var b = function a(x){
x && a(--x);
}
console.log(a);
(1) 函数表达式类似于局部变量,不会被全局作用域访问到,所以这里的函数 function a 是局部变量,外部无法访问,因此全局a还是1;
(2) console.log(a); //1
3
function a (x) {
return x * ;
}
var a;
console.log(a);
javascript永远是先解析声明函数,再解析变量, 执行顺序如下:
(1) 解析函数a;
(2) 声明变量var a; 因为a此时并没有被赋值,所以它为 undefined, 还是指向原来的值,即函数 function a;
(3) console.log(a); // function a
4
function b (x, y, a) {
arguments[] = ;
console.log (a);
}
b(, , );
函数内部,可以引用一个类数组的对象arguments,它并不是真正的数组,代表了函数实际接受参数的集合,可以通过下标对相应参数进行访问,
如果修改了此对象的属性,如arguments[index],则被传进来的第index (如果有的话,下标从0开始) 变量的值也会被修改。
执行顺序:
(1) 声明一个函数b;
(2) 执行函数b(1,2,3);因为这里arguments[2]与变量a引用的是同一个值,所以当arguments[2]改变时,a也随之改变。
(3) console.log(a) // 10;
5
function a () {
console.log(this);
}
a.call (null);
call 调用一个对象的一个方法,以另一个对象替换当前对象。
格式如 call(thisObj, arg1,arg2...argN);
在函数体外部调用call()方法,如果传入null,则默认转成window,如果不传也是一样,即函数中的this指向window。
console.log(this) // window;
function a () {
console.log (this === window);
}
console.log(this === window); // true
a.call (); // true
a.call (null); // true
a.call (this); // true
a.call (window); // true
a(); // true
6
function fo(){
console.log(a);
}
function foo(){
var a = ;
fo();
}
foo();
先执行 foo 函数, fo 虽然在foo调用,但是 fo函数是声明在全局作用域下的,所以fo中引用的a,是指向全局的window,而全局作用域下的a 并未声明,虽然在 foo 下,声明了var a=2,但它作为局部变量,无法被函数外的作用域所调用。
console.log(a) // a is not defined;
如果将以上代码写成:
function foo(){
var a = ;
function fo(){
console.log(a);
}
fo();
}
foo();
因为这时候,函数fo是声明在foo函数体内的,属于foo的内部函数,作用域链的访问顺序是由内向外的,a在fo里搜索不到,就会到上一级函数foo中 寻找,这里找到var a = 2 后返回结果。
console.log(a) // 2;
你自认为理解了JavaScript?的更多相关文章
- 深入理解:JavaScript原型与继承
深入理解:JavaScript原型与继承 看过不少书籍,不少文章,对于原型与继承的说明基本上让人不明觉厉,特别是对于习惯了面向对象编程的人来说更难理解,这里我就给大家说说我的理解. 首先JavaScr ...
- 理解的javascript自定义事件
理解的javascript自定义事件 被我拖延了将近一个月的javascript事件模型系列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情, ...
- 我想这次我真的理解了 JavaScript 的单线程机制
今天面试的时候被问到一个问题,是关于 JS 异步的.当时我脑海中闪过了一个单线程的概念,但却没有把真正的原理阐述清楚.所以回来特意重新回顾了前面单线程和异步相关的一些知识点. 虽然之前学习的时候也接触 ...
- JavaScript学习总结——我所理解的JavaScript闭包
一.闭包(Closure) 1.1.什么是闭包? 理解闭包概念: a.闭包是指有权限访问另一个函数作用域的变量的函数,创建闭包的常见方式就是在一个函数内部创建另一个函数,也就是创建一个内部函数,创建一 ...
- 个人理解的javascript作用域链与闭包
闭包引入的前提个人理解是为从外部读取局部变量,正常情况下,这是办不到的.简单的闭包举例如下: function f1(){ n=100; function f2(){ alert(n); } retu ...
- Javascript事件模型系列(四)我所理解的javascript自定义事件
被我拖延了将近一个月的javascript事件模型系列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情,公司的个人的,搞的自己心烦意乱浮躁了一 ...
- 我所理解的JavaScript闭包
目录 一.闭包(Closure) 1.1.什么是闭包? 1.2.为什么要用闭包(作用)? 1.2.1.保护函数内的变量安全. 1.2.2.通过访问外部变量,一个闭包可以暂时保存这些变量的上下文环境,当 ...
- 自己理解的javascript 的对象和类理解
首先需要先理解类和对象的意义,我个人理解如下: 类:对象的抽象化: 对象:类的实体: javascript中没有class关键字和类的用法,只能用伪类来做类的,所以要用function来定义累的名字: ...
- 理解ArcGIS Javascript Viewer Widget及编程模型
一个ArcGIS Javascript Viewer for JavaScript Widget是一组可以共享.迁移及部署到JavaScript View程序中的的文本文件.通常,一个程序员如果要开发 ...
随机推荐
- Ninject在mvc中的简单配置
前言 Ninject是一款开源的轻量级的依赖注入插件.从接触ioc以来,一直都是使用这个,感觉用起来还是不错的,配置起来也很方便简单.在mvc中更是基本傻瓜式的配置. 开发前的准备 新建一个mvc3项 ...
- c#使用DocX添加多级标题
博客转移到 http://jacean.github.io/ 继续分享编程经验 先上效果.可以生成多级标题,但是不能生成1,1.1,1.2这样的自动序列, 只是这样的效果. 实现方法是给Paragra ...
- [leetcode]_Best Time to Buy and Sell Stock I && II
一个系列三道题,我都不会做,google之答案.过了两道,第三道看不懂,放置,稍后继续. 一.Best Time to Buy and Sell Stock I 题目:一个数组表示一支股票的价格变换. ...
- 模拟新浪微博textarea,刷新页面输入信息保留
今天我们的产品经理提出一个新需求,模拟新浪微博textarea框,输入内容刷新页面保留信息. 我是用的方法是Html5 LocalStorage存储的,开始计划用cookie.或mysql存储,尝试了 ...
- 删:Centos 7安装Nginx 1.8
[CentOS 7] 安装nginx! 首先进行 nginx yum Nginx安装记录 注意:如果用源码安装,nginx配置时需要指定--with-pcer对应的压缩包路径,如果使用二进制安装不需要 ...
- java reflect 初始学习 动态加载类
首先要理解Class类: 在java 的反射中,Class.forName("com.lilin.Office") 使用类的全名,这样获取,不仅仅表示了类的类类型,同时还代表着类的 ...
- Android 创建单例模式的几种方法
java模式之单例模式:单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例.特点:1,一个类只能有一个实例2,自己创建这个实例3,整个系统都要使用这个实例 Singleton模式 ...
- “后PC”时代来临
“后PC”时代来临 数年前,喜达屋酒店及度假村国际集团将总部搬迁至美国康涅狄格州斯坦福,这也让公司首席执行官Frits van Paasschen有机会“除尘换新”. 那么,Frits van Paa ...
- Android Studio SDK 更新方法
通常情况下,下载Android SDK需要连接谷歌的服务器进行下载,由于国内水深火热的网络,速度基本为0.好在国内也有一个更新的镜像地址.本文章介绍如何在不FQ的情况下,使用国内镜像地址,更新andr ...
- php匿名函数小示例
<?php //$fun = function($params){ // echo $params; //}; // //$fun('aa'); //例一 //在普通函数中定义一个匿名函数 // ...