在我的职业生涯中,很早就已经开始使用JavaScript进行项目开发了。但是一直都是把重心放在了后端开发方面,前端方面鲜有涉及。所以造成的一个现象就是:目前的前端知识水平,应付一般的项目已然是足够的,但是火候尚缺,没有深入的进行研究,以至于总是谈论起来就发现自己半瓶子哐当的水平。为了解决这种尴尬的局面,决心潜心研究一段时间JavaScript,以下知识为本人学习过程中的总结,虽然以本人水平可能招致贻笑大方之果,但是更盼抛砖引玉之实。

在JavaScript中,我们调用一个普通的方法,可以通过如下的方式来进行:

//全局公共调用方式

function greetingMorning()
{
      alert("Hello Morning!");
}
greetingMorning();
//局部调用方式
var greetingWorld =function() {
      alert("Hello World!");
} greetingWorld();
//自调用方式
(function(){
      alert("Hello ChaoYang!");
})();

那么上面就是一般的三种调用方式,前两种都会在window对象上面进行附加,不同之处就在于,第一种是直接利用function进行声明方式,属于公共调用方式;第二种是利用var关键字进行申明的方式调用。也就是说,第一种申明方式所申明的函数,无论在函数体之前或之后调用,都没问题。而第二种申明方式所申明的函数,只能在函数体之后调用:

//正确,可以这么调用

greetingMorning();
function greetingMorning()
{
     alert("Hello Morning!");
}
//错误,提示找不到方法
greetingWorld();
var greetingWorld =function()
{
     alert("Hello World!");
}

在这里,我们需要注意的第一个坑就是局部变量加不加var关键字的问题:

function greetingLucy()

{
      name ="lucy";
      alert("Hello "+name);
}
greetingLucy();
alert(name);

这里我们的执行结果,第一次会输出: Hello lucy, 第二次会输出: lucy。 这很奇怪,为什么name我写到了方法里面,按理来说已经是局部变量了,为什么还是会输出结果呢?其实在JavaScript中,在方法体内,如果不加var关键字的话,会将此变量默认为全局变量。这也是为什么会输出结果的原因了。

那么知道了函数执行的一般方法,那么我们来看函数的执行的特殊方法。

如上所述,我们直接利用 (); 的方式可以出发函数的立即执行。但是这种执行,其实在大多数情况下是无法改变this关键字的作用域的,由于this默认指向的就是已经实例化过的window对象,所以很多时候当我们需要更改this的作用域的时候,我们就不得不引入 apply, call 关键字 以及 bind 关键字。 我们先来讲解他们的基本用法。

首先,对于apply方法:

//不带参数,我们apply了this,可以看出我们改变了this的作用域 //从原本的window对象,指向了greetingLucy

function greetingLucy()
{
      var name ="lucy"; alert("Hello "+name);
}
greetingLucy.apply(this);
 
//带两个参数
function greeting(name, age)
{
      alert("Hello "+ name +""+ age +" !");
}
]);

可以看出,使用apply的时候,其中第一个参数一定要指向需要应用的对象,之后的多个参数需要写成数组的方式。

再来看看call方法:

function greetingLucy()

{
      var name ="lucy";
      alert("Hello "+name);
}
greetingLucy.call(this);
 
function greeting(name,age)
{
      alert("Hello "+ name +""+ age +" !");
}
);

可以看出,使用call的时候,第一个参数也是需要指向被调用的对象,之后的多个参数可以直接写就行。

从这里我们可以看出,apply和call都会改变this的作用域,至于更详细的信息,我会放到第二节去讲解。

下面我们来看看bind方法。

var color ="red";

var obj = {color:"blue"};
function sayColor()
{
      alert(this.color);
}
var nw = sayColor.bind(obj);
//执行
nw();

这里会输出什么呢? 这里会输出“blue”。那为什么不会输出red呢? 其实在这里,this关键字有个很重要的特点,那就是: 谁调用我,我指向谁。由于bind方法的调用,会导致this指向的改变,从window对象变成了指向obj对象。所以这里会拿obj对象中的color来执行。

从上面的例子我们也可以看出,bind方法不会导致函数的立即执行,需要触发才可以执行。

为什么bind不会立即执行呢? 我们可以执行 alert(nw)看出返回给我们的结果:

function bound sayColor(){[native code]}

这说明bind以后返回的nw对象,就是一个函数,并且还是未执行的函数,如果我们想执行,就需要加上 ();

好了,这里就是我所理解的 apply call bind的用法了。

其实他们的用法很基础,但是他们可以改变this作用域的这个特点倒是杀伤力惊人。后面的章节我会重点讲解this,争取将其吃透。敬请期待。

前端见微知著JavaScript基础篇:你所不知道的apply, call 和 bind的更多相关文章

  1. 前端见微知著JavaScript基础篇:this or that ?

    上节,我们提到了this关键字的问题,并且追加了一句很有意义的话:谁调用我,我指向谁.的确,在javascript中,在默认情况下,this会指向一个已经初始化的window对象.所以你不论有多少全局 ...

  2. C#线程篇---你所不知道的线程池(4)

    线程的创建和销毁都要耗费大量的时间,有什么更好的办法?用线程池! 太多的线程浪费内存资源,有什么更好的办法?用线程池! 太多线程有损性能,有什么更好的办法?用线程池!(⊙_⊙)? 线程池是什么?继前三 ...

  3. 关于JavaScript对象,你所不知道的事(二)- 再说属性

    说完了对象那些不常用的冷知识,是时候来看看JavaScript中对象属性有哪些有意思的东西了. 不出你所料,对象属性自然也有其相应的特征属性,但是这个话题有点复杂,让我们先从简单的说起,对象属性的分类 ...

  4. 关于JavaScript对象,你所不知道的事(一)- 先谈对象

    这篇博文的主要目的是为了填坑,很久之前我发表了一篇名为关于JavaScript对象中的一切(一) - 对象属性的文章,想要谈一谈JavaScript对象,可那时只是贴了一张关于这个主题的思维导图,今天 ...

  5. 【javascript杂谈】你所不知道的replace函数

    前言 最近在做面试题的时候总会用到这个函数,这个函数总是和正则表达式联系到一起,并且效果很是不错,总能很简单出色的完成字符串的实际问题,大家肯定都会使用这个函数,像我一样的初学者可能对这个函数的了解还 ...

  6. 你所不知道的 CSS 滤镜技巧与细节

    承接上一篇你所不知道的 CSS 动画技巧与细节,本文主要介绍 CSS 滤镜的不常用用法,希望能给读者带来一些干货! OK,下面直接进入正文.本文所描述的滤镜,指的是 CSS3 出来后的滤镜,不是 IE ...

  7. JavaScript中你所不知道的Object(二)--Function篇

    上一篇(JavaScript中你所不知道的Object(一))说到,Object对象有大量的内部属性,而其中多数和外部属性的操作有关.最后留了个悬念,就是Boolean.Date.Number.Str ...

  8. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

  9. 你所不知道的 CSS 阴影技巧与细节 滚动视差?CSS 不在话下 神奇的选择器 :focus-within 当角色转换为面试官之后 NPOI 教程 - 3.2 打印相关设置 前端XSS相关整理 委托入门案例

    你所不知道的 CSS 阴影技巧与细节   关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow  ...

随机推荐

  1. 使用开源免费类库在.net中操作Excel

    自从上次找到NPOI之后,根据园友提供的线索以及Google,又找到了一些开源免费的类库,所以都简单体验了一遍. 主要找到以下类库: MyXls(http://sourceforge.net/proj ...

  2. Jmeter教程索引贴

    新的一年即将到来,不知不觉2015年自己在Jmeter方面总结的文章有十几篇,在此汇总一下,顺便也算是个总结吧.2016年,继续学习技术,总结,写文章. 一.基础部分: 使用Jmeter进行http接 ...

  3. Oracle表字段的增加、删除、修改和重命名

    本文主要是关于Oracle数据库表中字段的增加.删除.修改和重命名的操作. 增加字段语法:alter table tablename add (column datatype [default val ...

  4. 重新认识mapreduce

    写这篇文章,是因为最近遇到了mapreduce的二次排序问题.以前的理解不完全正确.首先看一下mapreduce的过程 相信这张图熟悉MR的人都应该见过,再来一张图 wordcount也不细说了,ha ...

  5. TCP连接建立系列 — 服务端接收ACK段(一)

      http://blog.csdn.net/zhangskd/article/details/17923917 分类: Linux TCP/IP Linux Kernel 2014-01-07 09 ...

  6. 使用Tcmalloc进行堆栈分析

    在前一篇译文<使用TCmalloc的堆栈检查>,介绍了Tcmalloc进行堆栈检查,今天翻译<heap-profiling using tcmalloc>,了解如何 TCmal ...

  7. [To be translated] Nova:libvirt image 的生命周期

    翻译自:http://www.pixelbeat.org/docs/openstack_libvirt_images/ The main stages of a Virtual Machine dis ...

  8. MMORPG大型游戏设计与开发(客户端架构 part4 of vegine)

    昨天是七夕,祝大家都过的快乐,希望这句迟到的问候不会造成大家心中的困扰.这一节讲到了前端比较重要的模块,性能以及调试异常模块.一个应用的性能往往是最核心的部分,就像人身体的各个器官一样,一小部分也不能 ...

  9. 怎样用好ZBrush 中的映射大师功能

    Projection Master可以理解为映射大师它是ZBrush®中一个独特的功能,允许在3D模型中使用2D和2.5D笔刷,用户可以利用此功能将绘制的颜色. Texture及纹理等映射到模型表面. ...

  10. Java开发之JSP行为

    一.Java Bean行文 1.重点说明 Java Bean行为是一组与Java Bean相关的行为,包括useBean行为.setProperty行为.getProperty行为等.Java Bea ...