在我的职业生涯中,很早就已经开始使用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. 计算机网络和Internet之核心网络

    1.网状的路由器 路由器的链接组成了网络的核心. 任何一个路由器,或者某条线路挂掉,但是网络还是通的,这是internet的一个特性. data到底是怎么传输的? 1)circuit switchin ...

  2. #VSTS日志# 2015/12/10 – 终于可以删除工作项了

    最近的更新不少,废话少说,直接上干货 定制工作项字段 本周的更新后,所有的用户都可以在vsts上直接给工作项添加字段了,具体内容包括– 添加新字段(日期,字符串,整形,数字)– 字段显示位置配置– 过 ...

  3. JAVA中的枚举小结

    枚举 将一组有限集合创建为一种新的类型,集合里面的值可以作为程序组件使用: 枚举基本特性 以下代码是枚举的简单使用: 使用values方法返回enum实例的数组 使用ordinal方法返回每个enum ...

  4. Proactor VS Reactor

    proactor vs reactor 先发几本proactor 与 reactor 相关的电子书: http://files.cnblogs.com/files/f1194361820/reacto ...

  5. SQL server基础知识(表操作、数据约束、多表链接查询)

    SQL server基础知识 一.基础知识 (1).存储结构:数据库->表->数据 (2).管理数据库 增加:create database 数据库名称 删除:drop database ...

  6. 虚拟机centos6.5 --安装jdk

    1.首先卸载默认安装的openjdk,如下 rpm -qa | grep java #查看当前是否已经安装了跟java有关的包 yum -y remove java #卸载 rpm -qa |grep ...

  7. c++11 新特性之lambda表达式

    写过c#之后,觉得c#里的lambda表达式和delegate配合使用,这样的机制用起来非常爽.c++11也有了lambda表达式,形式上有细小的差异.形式如下: c#:(input paramete ...

  8. Android+Sqlite 实现古诗阅读应用(二)

    传送门:Android+Sqlite 实现古诗阅读应用(一) Hi,又回来了,最近接到很多热情洋溢的小伙伴们的来信,吼开心哈,我会继续努力的=-=! 上回的东西我们做到了有个textview能随机选择 ...

  9. Jetty使用攻略

    jetty作为一款小型的web容器用处很大,因为其小巧强大,经常作为嵌入式的组件处理http交互. Jetty 作为一个独立的 Servlet 引擎可以独立提供 Web 服务,但是它也可以与其他 We ...

  10. jdk8-日期

    今天遇到了日期问题,看了下jdk8新特性 http://www.ibm.com/developerworks/cn/java/j-lo-jdk8newfeature/index.html Java 的 ...