javascript之观码说理
前一阶段看到大神在网上贴出的测试个人js理解的代码。
在此我在此借用大神的代码,进行自我复述,大神文章参见:http://www.imooc.com/article/1731
代码1:
function foo(){
console.log(this.a);
}
function doFoo(fn){
fn();
}
function doFoo2(o){
o.foo();
}
var obj = {
a: 2,
foo: foo
};
var a = "I'm an a";
doFoo(obj.foo);
doFoo2(obj);
我的理解:
先说doFoo(obj.foo)
传入的参数obj.foo即对象obj的元素foo,内容为foo。
此时传入的foo在方法doFoo中就变成了调用foo()方法。
因为foo()是定义在最外层的,此时的this指向最外层对象window,所以取得的a应该是在最外层定义的 var a = "I'm an a";。
所以第一个方法返回的是I'm an a。
其次说doFoo2(obj)
传入的参数是obj对象.
此时在doFoo2中调用的是obj.foo()。
这时foo()方法中的this重新指向了obj对象,所以this.a取得的是obj对象中的a。
所以第二个方法返回的是2.
大神的分析:
在Javascript中,this指向函数 执行时的当前对象,而非声明环境有。
执行doFoo的时候执行环境就是doFoo函数,执行环境为全局。
执行doFoo2时是在对象内部调用函数,this指针指向该对象。
代码2:
function foo(somthing){
console.log(this.a, somthing);
}
function bind(fn, obj){
return function(){
return fn.apply(obj, arguments);
}
}
var obj = {
a:2
}
var bar = bind(foo, obj);
var b = bar(3);
console.log(b);
第二段代码,再次先说我自己的理解:
结论先行:这里展示apply的作用-修改方法作用的对象,也可以说是修改this的指向
解释:
原本在foo函数的定义中,this指向的是全局对象,而在函数bind中,利用apply,bind将this指向了obj,即fn方法实际作用在obj上了。
之后的代码便是定义一个obj对象直接量,然后将利用bind方法将foo方法的作用对象指向了obj,最后再通过定义的bar传入参数"3"。
也就是说,在最后bar(3)执行的时候,调用的方法foo作用于对象obj上(这里的obj指的是已经定义的对象直接量),所以方法执行的是下面的内容:
console.log(obj.a,3);
而obj的a是2,所以输出的内容是2 3。
再次看大神的分析,发现自己漏掉了最后方法没有返回参数,所以还会返回一个undefined。
贴上大神的分析:
apply、call、bind都有个作用就是改变作用域,这里用apply将foo函数的作用域指向obj对象,同时传入参数。
再简单分析一下bind函数内部的嵌套,执行bind函数的时候返回的是一个匿名函数,所以执行bar(3)的时候实际上是执行的bind内部的匿名函数,返回的是之前传入的foo函数的执行结果。
函数没有返回值的情况下默认返回undefined。
代码3:
function foo(a,b){
this.val = a+b;
}
var bar = foo.bind(null, 'p1');
var baz = new bar('p2');
console.log(baz.val);
未完待续
javascript之观码说理的更多相关文章
- Javascript 二维码生成库:QRCode
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- JavaScript特效源码(1、文字特效)
注:本文以及以下关于Javascript特效源码都是分享自JavaScript源码大全. 1.逐隐逐现的的特效 逐隐逐现的文字特效[推荐使用][适用于IE4++] (修改显示的文字后根据说明进行共2步 ...
- JavaScript二维码生成——qrcode.js
在开发中,有时候,我们需要根据不同的内容来动态生成二维码,则可以使用qrcode.js这个小插件来实现. 1.qrcode.js文件内容: (1)未压缩(qrcode.js): /** * @file ...
- javascript Base64转码解码
javascript 使用btoa和atob来进行Base64转码和解码 $scope.checkAddCookie = function() { var expireDate = new Date( ...
- 使用C#重写网上的60行 Javascript 俄罗斯方块源码 (带注释)
在很久很久以前,就已经看过 60行Js的俄罗斯方块源码.无奈当时能力不够看明白,当时觉得就是个神作. 现在总算有空再看了,顺便用c#实现一遍(超过60行),顺道熟悉下Js API. 网上其他博客也有分 ...
- JavaScript特效源码(4、鼠标特效)
1.鼠标感应--渐现特效 鼠标感应渐显图片[平时很模糊的图片鼠标一放上就显示清楚] [修改图片名称即可][共2步] ====1.将以下代码加入HTML的<head></head> ...
- JavaScript特效源码(8、其他特效)
1.中文日期 中文日期[无须修改][共1步]] ====1.将以下代码加入HEML的<body></body>之间 <script LANGUAGE="Java ...
- JavaScript特效源码(7、页面特效二)
7.将站点加入频道栏 将站点加入频道栏[看详细说明] ====1.加入channel的方法:使用如下连接指向你的频道文件*.cdf. <a href="javascript:windo ...
- JavaScript特效源码(6、页面特效一)
1.页面全屏 页面全屏显示[ALT+F4关闭][共1步][新弹出窗口并以全屏幕方式显示] ====1.将以下代码加入HTML的<body></body>之间: <form ...
随机推荐
- Python学习——基础篇
1.python的安装 python下载地址:https://www.python.org/downloads/ 安装完成后,运行cmd.exe,输入python 如果出现“p ...
- mysql存储过程简介
创建存储过程CREATE PROCEDURE productpricing(OUT pl DECIMAL(8,2),OUT ph DECIMAL(8,2),OUT pa DECIMAL(8,2))BE ...
- Linux:基础配置--备忘
1.网络 /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 HWADDR=08:00:27:77:F3:A1 TYPE=Ethernet UU ...
- ORACLE SQL前端补0的三种方式。
前端补0的三种方式. select lpad(sal,8,'0') from emp;select to_char(sal,'00000000') from emp;select substr('00 ...
- NHibernate系列文章六:NHibernate数据类型映射
摘要 NHibernate支持所有的数据库数据类型. 以SQL Server数据库为例,下表是NHibernate支持的SQL Server数据库最常见的数据类型对照表. 第一列是NHibernate ...
- Python urllib模块urlopen()与urlretrieve()详解
1.urlopen()方法urllib.urlopen(url[, data[, proxies]]) :创建一个表示远程url的类文件对象,然后像本地文件一样操作这个类文件对象来获取远程数据.参数u ...
- 配置 node.js 环境
安装 Node.js 1. 下载 Node.js, 首先到官网 http://nodejs.org/download/ 的下载页面下载 Windows 版本, 这里有两种版本,推荐 .msi 的安装程 ...
- c 数据拼接
char buf1[] = {0x31,0x32,0x33,0x00,0x51,0x52,0x53,0xaa,0xbb,0xcc,0x00}; int a=0xabcd6799; int b=0x88 ...
- Action类中获取request等对象的方法
struts2中的action类中,SevletActionContext可以获取
- scala 学习: case class
case class: 1.定义为case class 的类在实例化时,可以不使用new 关键字. case class People(name:String, age:Int) val zhangs ...