JavaScript的因为所以
各位看官,楼主开始说过写几篇博客,这是这个系列的最后一集。吾以为:了解JavaScript的身世之谜,掌握其近乎心想事成的变量系统,了解其解析运行的偷梁换柱之法,熟悉布大师迂回曲折的OOP实现。那你离height level也不远了。当然,要想height level还要再掌握两个常常被各位园友挂在嘴边的东西:this与闭包。this是什么鬼?闭包又是什么鬼?照本宣科的概念,这里不说,我们只聊“因为所以”。废话少说,开聊!
this是什么鬼?
this这玩儿称呼为鬼一点不为过,好多小白一看满屏都是this的脚本瞬间眩晕。看样子有点像Java、C#之类的this,但凭直觉好像又超越了Java、C#的this,看得是隐隐约约、似懂非懂。各种度娘、G哥大部分得到的都是照本宣科的解析。用心的会记下并研究的,无心的大大咧咧过目而已。于是乎,好多老鸟都没彻底搞清楚this是什么鬼。要想了解this是什么鬼,那得先了解这鬼是怎么来的。
话说JavaScript的设计初衷是过程式的,后面布大师为了紧跟时代潮流,迂回曲折地实现OOP,为此引入了this来表示实例对象。OOP是实现,但是JavaScript的世界从此多了一个this。this在应用于JavaScript的OOP时候,表示的是实例本身。但是如果我写的JavaScript并不需要new对象,而是随意到处写了this,那这个时候this代表什么?真所谓填一坑挖一坑啊!有坑得填啊,于是,布大师又想折子给这个this赋予意义了:当this应用于OOP的时候,它表示实例本身;而当this应用于非OOP的时候则表示this所在元素的归属对象。这话说来说去还是有点抽象,看代码最实在:
1)当this在function中,但是funciton只是过程式函数
<script>
/**解析:
*test在这里只是个过程式的函数,没有玩OOP
*调用test函数打印this,那这里的this指的就是test函数的归属
*而test函数是归属到当前Window对象上的
* ****/
function test(){
console.log(this); //结果是 Window对象
}
test();
</script>
2)当this在某个非实例化的对象中
<script>
/**解析:
*这里的this被定义一个名为f的函数中
*f函数归属的是obj对象
*结果:this代表obj对象
* ****/
var obj={
a:123,
f:function(){
console.log(this);//结果 是obj对象
console.log(this.a);//结果是123
}
};
console.log(obj.f());//结果
</script>
3)当this应用于OOP的玩法中
<script>
/**解析:
*clazz是一个类的构造函数,用于创建clazz的实例对象
*this在这里就表示每一个new出来的对象
* ****/
function clazz(a,b){
this.a=a;
this.b=b;
this.print=function(){
console.log(this.a+this.b);
};
}
var c1=new clazz(1,1);
c1.print(); //打印:2
var c2=new clazz(2,2);
c1.print(); //打印:4
</script>
4)当this被偷梁换柱
<script>
/**解析:
*利用call或者apply让f函数运行期间的this指向另一个对象
* ****/
var obj={
a:123,
f:function(){
console.log(this);//结果 是obj对象
console.log(this.a);//结果是 undefined
}
};
//利用call或者apply让f函数运行期间,将this换成当前window
obj.f.call(this);
</script>
闭包是什么鬼?
咱们还是废话少说,按套路,先了解这个所谓的闭包是怎么来的。全世界(写代码的人)都知道,像c、java、c++这些言语都有一套一套严格的语法,特别像数据类型、函数的定义都有自己规则,不是你想怎么写就写的。但是JavaScript这玩儿,被布大师设计得你想怎么写就怎么写,竟然可以函数里面再定义函数,可见自由度之大。你再看看java、c++能这样干嘛?自由是自由了,但是这玩法引出了一个问题:但凡大学里认真念过点书的鞋同都知道,函数是基于栈运行的,如果函数嵌套函数,子函数又引用了父函数里定义的成员,当父函数已经over的时候,按常规套路,父函数出栈了,它定义的成员也应该被Over了,如果此时子函数还活着,那它引用的父函数变量又不见了,那子函数就没法用了。于是乎,布大师又不得不给这个bug做补丁,闭包这玩儿就出生了。那咱们通俗给闭包来个定义吧:
闭包:活着的人从死去的人那里偷来了东西,让那些东西不随死去的人而消失。活着的人拥有了这些东西,这些东西的寿命也因此边长了。这是JavaScript为了应对天马行空的自由度产生的bug而打的补丁!
这比如虽然有点不雅,但也只是为了看官便于理解,请勿介意。好,咱们还是看看代码分析:
<script>
function oldMan(){
var money=999999;// 老人的财富
//老人有一个年轻的儿子
return function young(){
console.log("儿子要花老子的钱"+money+"美刀");
}
}
var y=oldMan();//老人将儿子放出来之后就挂了,oldMan函数运行完成,出栈了!!
y();//儿子开始活动了,儿子竟然有老人的钱
</script>
看官,不知道你看了这寥寥几十字的通俗解法,是否还对那个所谓的闭包还怀抱敬畏呢!
如果你认真看这寥寥几篇的通俗博文,我相信你对JavaScript的认识肯定是另一个阶梯。当然要想在前端立足,仅仅掌握JavaScript还不足以混饭,你还得懂HTML、CSS。楼主打算接下来就这两个知识再聊上几篇。如有兴趣,请留意!其他JavaScript的问题,也欢迎一起学习探讨!
JavaScript的因为所以的更多相关文章
- JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议
软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- Javascript 的执行环境(execution context)和作用域(scope)及垃圾回收
执行环境有全局执行环境和函数执行环境之分,每次进入一个新执行环境,都会创建一个搜索变量和函数的作用域链.函数的局部环境不仅有权访问函数作用于中的变量,而且可以访问其外部环境,直到全局环境.全局执行环境 ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- 读书笔记:JavaScript DOM 编程艺术(第二版)
读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...
- 《Web 前端面试指南》1、JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
- JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
今天为大家分享一下我自己制作的浏览器滚动条,我们知道用css来自定义滚动条也是挺好的方式,css虽然能够改变chrome浏览器的滚动条样式可以自定义,css也能够改变IE浏览器滚动条的颜色.但是css ...
- JavaScript进阶之路(一)初学者的开始
一:写在前面的问题和话 一个javascript初学者的进阶之路! 背景:3年后端(ASP.NET)工作经验,javascript水平一般般,前端水平一般般.学习资料:犀牛书. 如有误导,或者错误的地 ...
- 梅须逊雪三分白,雪却输梅一段香——CSS动画与JavaScript动画
CSS动画并不是绝对比JavaScript动画性能更优越,开源动画库Velocity.js等就展现了强劲的性能. 一.两者的主要区别 先开门见山的说说两者之间的区别. 1)CSS动画: 基于CSS的动 ...
随机推荐
- 本地Git环境配置
在Git Bash下获取源码时,提示permission denied publickey. 原因是本地帐号配置不正确,解决办法 生成SSH文件 1,进入Git Bash 2, 输入下面文字 ssh ...
- source 命令
作用: 当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile 介绍:source命令也称为“点命令”,也就 ...
- 嵌入式 十个最值得阅读学习的C开源项目代码
开源世界有许多优秀的开源项目,我选取其中十个最优秀的.最轻量级的C语言的项目,希望可以为C语言开发人员提供参考. 十个最值得阅读学习的C开源项目代码 1. Webbench 2. Tinyhttpd ...
- hdu 5444 Elven Postman(根据先序遍历和中序遍历求后序遍历)2015 ACM/ICPC Asia Regional Changchun Online
很坑的一道题,读了半天才读懂题,手忙脚乱的写完(套上模板+修改模板),然后RE到死…… 题意: 题面上告诉了我们这是一棵二叉树,然后告诉了我们它的先序遍历,然后,没了……没了! 反复读题,终于在偶然间 ...
- JS方式调用本地的可执行文件
看到一个方法,有些用,先存下来,有用的时候再用. 前几天,在IE,FIREFOX中实现了用JS方式调用本地的可执行文件.地址:www.yihaomen.com/article/js/211.htm , ...
- 使用Ajax在javascript中调用后台C#函数
使用Ajax在javascript中调用后台C#函数 最近一段时间在紧跟一个网站的项目,数据库中用户表的UserName要求是唯一的,所以当用户选定一个用户名进行注册时要首先检查该用户名是否已被占用, ...
- 七牛云实现js上传
七牛云的官方API写的一塌糊涂.最主要的,还是版本兼容的问题. 一.引入文件 引入了两个文件: 1.jquery-1.10.2.min.js 2.plupload.full.min.js 3.qini ...
- C语言实现strlen
strlen: #ifndef STRLEN_H #define STRLEN_H #include <stdio.h> // 参考微软的写法 int cat_strlen(const c ...
- CentOS7 安装 scala 2.11.1
wget http://downloads.typesafe.com/scala/2.11.6/scala-2.11.6.tgz?_ga=1.61986863.2013247204.144801902 ...
- SQL和NOSQL有区别吗?
在大数据高速发展的今天,数据量在不断的增加,传统的数据库可能不能满足人们的需求了,这个时候新霸哥注意到了NOSQL出现了可以解决这个问题.我们知道sql数据库可以存储数据和处理数据,但是NOSQL最大 ...