深入浅出javascript(八)this、call和apply
_________此篇日志属于重要记录,长期更新__________
this,call,apply这三个是进阶JS的重要一步,需要详细的记录。
➢ this
一、作为对象的方法调用。
当函数作为对象的方法被调用时,this指向该对象。
首先,函数必须作为对象的方法。这句话很关键,因为函数的调用有很多种可能,在后面会展现。示例1-1:
var o = {
name: 'o',
get: function () {
return this.name;
}
}
console.log(o.get());//输出'o'
get方法是被对象o调用的,所以this指向o,这是没有异议的。
现在把这个例子改下,示例1-2:
var o = {
name: 'o',
get: function () {
return this.name;
}
};
var g = o.get; //将o的get方法赋给g;
console.log(g()); //输出空;
o.get方法赋给g之后,现在这个方法g和原来的对象o已经没有关系了,因为g是全局的,所以它属于window的方法,结果导致方法内的this已经指向window,又,window没有定义name属性,所以输出为空。
从这两个例子的对比可以看出,this是随机而动的,谁绑定,this就指向谁。
二、做为普通函数调用
这里所说的普通函数调用主要是为了和狭隘的 ' 对象的方法调用 ' 来区别。因为无论函数怎么调用,它总属于一个对象,因为最外层总有一个window对象。
如上例所示,将函数赋值给另一个变量,就是将这个函数从对象中 ’ 复制一份 ‘ 出来,结果变成window对象的一个方法,因此this指向window。
示例2-1
1.创建变量o,因为是全局的,所以内部的this为window,其内部的g也属于普通函数调用,因此也指向this。
三、函数到底出现在哪儿?
函数到底出现在哪里,说的是函数究竟出现在哪种地方,只有将出现的这几种地方弄明白,才能对函数做更深入的了解,总结如下:
1 | 普通函数 |
2 | 普通函数内部的普通函数 |
3 | 对象内部 |
4 | 对象内部的函数的内部 |
➢ 四种可能:
普通函数 this=window |
普通函数内部的普通函数 this=window |
对象内部函数 this=对象 |
对象内部函数内部的普通函数 this=window |
function f() { |
function f() { |
var o = { |
var o = { |
现在可以推断两条结论:
一、凡是普通函数都指向window
二、凡是对象调用都指向对象。(这里的对象是狭隘的对象,即自创建的对象)
换句话说,凡遇到一个函数,首先两问:
一、这个函数是普通函数吗?[如果是,则this=window]
二、这个函数是被对象调用的吗?[如果是,则this=对象]
※ 回过头再看前面的一句话:当函数作为对象的方法被调用时,this指向该对象,也就可以理解了。
四、做为构造函数
做为构造函数比较简单,this指定绑定的对象。仅示例:
var F = function () {
this.name = 'F';
};
var f=new F();
➢ apply和call
一、概述
apply就是函数调用,而调用的就是函数fn,也就是说执行fn( )。 apply后面是(对象,参数)。参数可以是数组,可以是➀类数组。
所以理解这个apply就是记住两个点:
1.调用函数fn.
2.传入对象,如果传入的对象为null,则this=window
apply概括:调用函数fn,fn需要依赖传入的对象来确定它内部的this到底指向谁。
示例1-1:
window.name = 'window';
function f() {
console.log(this.name);
}
f.apply(null); //输出'window'
首次接触的时候有点点绕。
示例1-2:
function f() {
console.log(this.name);
}
var o = {
name: '对象o'
};
f.apply(o);
二、作用
1、改变this的指向
首先,这个this指的是谁呢?肯定是fn内部的this。如果函数没有this,那又何谈改变this的指向呢。现在先做一个带有this的函数。
function f() {
console.log(this.name);
}
this是可以随意绑定的,这就是apply的作用,做个图示例一下:
function f() {
console.log(this.name);
}
var o = {
name: 'o'
};
如上代码所示,f.apply(o),f内部的this绑定了对象o。
2、借用其它对象的方法——继承
这种继承是继承方法中的一种 [ 关于Javascript继承详细,参看记录 ],其实说起来更像是 ‘复制’。即:将父类中的属性复制一份到子类,代码2-1:
/***构造继承最简化的形式***/ //父类
function subClass() {
this.name = 'subClass';
}
//子类
function superClass() {
subClass.call(this);
}
var o = new superClass();
console.log(o.name); //输出'subclass'
➢ 代码解析:
子类构造函数使用父类.call,并将子类自己的this代入,结果就是将父类的属性 '复制' 了一份给子类。
3、类数组的使用(重要!)
补充于2018-10-23 20:12:51
类数组一个比较常见的例子是arguments。这个东西像数组但又不是数组,如果采用一般的数组方法是不可行的,必须采用数组的call调用。
示例如下:
arguments.join(","),#这条语句希望将函数参数用","连接起来形成字符串,但是代码错误不能通过。这里采用Array原型方法调用:
Array.prototype.join.call(arguments,",");
这一条的应用比较常用且重要,也是采用call调用的一个比较独特的例子。
4、
深入浅出javascript(八)this、call和apply的更多相关文章
- Javascript中call函数和apply函数的使用
Javascript 中call函数和apply的使用: Javascript中的call函数和apply函数是对执行上下文进行切换,是将一个函数从当前执行的上下文切换到另一个对象中执行,例如: so ...
- 深入浅出 JavaScript 对象 v0.5
JavaScript 没有类的概念,因此它的对象与基于类的语言中的对象有所不同.笔者主要参考<JS 高级程序设计>.<JS 权威指南>和<JS 精粹> 本文由浅入深 ...
- 从头开始学JavaScript (八)——变量
原文:从头开始学JavaScript (八)--变量 一.变量分类: 基本类型值:null.undefined.number.string.Boolean: 引用类型值:保存在内存中的对象,如:Obj ...
- 深入浅出 JavaScript 关键词 -- this
深入浅出 JavaScript 关键词 -- this 要说 JavaScript 这门语言最容易让人困惑的知识点,this 关键词肯定算一个.JavaScript 语言面世多年,一直在进化完善,现在 ...
- Javascript 中的 call 和 apply
发表于 2012年02月1日 by 愚人码头 原文链接:http://www.css88.com/archives/4431 JavaScript 中通过call或者apply用来代替另一个对象调 ...
- 深入浅出JavaScript之this
JavaScript中的this比较灵活,根据在不同环境下,或者同一个函数在不同方式调用下,this都有可能是不同的.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 下面是我的学习笔记 ...
- 【转】深入浅出JavaScript之this
JavaScript中的this比较灵活,根据在不同环境下,或者同一个函数在不同方式调用下,this都有可能是不同的.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 下面是我的学习笔记 ...
- javascript中call函数与apply
javascript中的call方法使当前对象可以调用另一个对象的方法,即改变this的指向内容 var first_object = { num: 42 }; var second_object = ...
- 深入浅出 JavaScript 中的 this
在 Java 等面向对象的语言中,this 关键字的含义是明确且具体的,即指代当前对象.一般在编译期确定下来,或称为编译期绑定.而在 JavaScript 中,this 是动态绑定,或称为运行期绑定的 ...
随机推荐
- BadgeView 圆形数字提醒 购物车常用
实际上BadgeView这个类就是继承TextView的.很多TextView中设置字体的方法都适用于BadgeView. 1. setTargetView(View) --> 设置哪个控件显示 ...
- centos实现两种秒级任务的简单方法
1.通过写shell脚本,死循环,守护进程运行 > vi /data/sec.sh #!/bin/bash while true do #写上自已的命令 echo "hello wor ...
- [z]根据awr报告查看最慢的sql语句
http://blog.itpub.net/12679300/viewspace-2125679/ 当系统运行了一段时间后,系统基本也趋于稳定了,SQL调优也变了DBA的一个主要的工作内容,很多时候都 ...
- devexpress WinForms MVVM
WinForms MVVM This section is dedicated to the Model-View-ViewModel (MVVM) architectural pattern. Yo ...
- 时间处理:计算下一天日期,如输入"2004/12/31"(注释2014年12月31日),则输出"2005/1/1".
/* ============================================================================ Name : Exercise.c Au ...
- 8M - 三角形
用N个三角形最多可以把平面分成几个区域? Input 输入数据的第一行是一个正整数T(1<=T<=10000),表示测试数据的数量.然后是T组测试数据,每组测试数据只包含一个正整数N(1 ...
- Lazarus下面的javascript绑定另外一个版本bug修正
Lazarus下面的javascript绑定另外一个版本bug修正 从svn 检出的代码有几个问题 1.fpcjs.pas 单元开始有 {$IFDEF FPC} {$MODE delphi} {$EN ...
- readv writev示例程序
当 readv() 时候,需要程序自己提供space,接收数据. #include <stdio.h> #include <stdlib.h> #include <str ...
- 判断某个字符串里面是否包含caoyang 这个字符串?
$string = 'Lorem ipsum dolor sit amet'; $preg = '/caoyang/'; $status = preg_match($preg, $string,$ma ...
- PHP ini 配置无效的坑给自己记录
装redis 扩展时,发现装成功之后扩展一直加载不上, 于是phpinfo 发现Configuration File (php.ini) Path:none Loaded Configuration ...