javascript中this指针探讨
javascript是一门类java语言有很多跟java相类似的特点,但也仅是类似而已,真正使用中还是有很大的差别。this指针常常让很多初学者抓狂,本人也曾为此困惑不解,查找过很多资料,今天在这里总结一下,希望能帮助后来者更快驯服这只拦路虎。网上有很多讲解this指针的文章其中不乏精品,以我看来了解this指针关键在于掌握javascript中函数的四种调用模式。那么什么是调用?调用指的是跟在任何产生一个函数值的表达式之后使用"()",obj.f()这种方式成为调用,obj.f这种方式称为访问。
一、方法调用模式:
在该调用模式中函数作为一个对象的方法被调用:obj.fun()。当函数以此种形式被调用时this指针绑定到调用该方法的对象上即obj。
var myObj = {
value: 0,
increase: function(){
this.value++;
console.log(this.value);
}
};
// this绑定到myObj对象上
myObj.increase(); //
myObj2 = {
value: 10
};
myObj2.increase = myObj.increase;// myObj2与myObj的increase指向同一函数引用地址
// this绑定到myObj2对象上
myObj2.increase(); //
所以在将一个html元素的某一事件绑定某一函数时,若函数中使用this指针,则this指针会被绑定到该元素上。
var ele1 = document.getElementById('id');
ele1.addEventListener('click', myObj.increase, false);
// 该绑定相当于
ele1.onclick = myObj.increase;
// 事件触发时即相当于调用click方法
ele1.click(); // 与上文中myObj2.increase一个道理,若ele1中没有value属性则会报错
二、函数调用模式:
当函数没有当做方法调用即没有被一个对象通过点语法,这时它被当做一个函数来调用。以此模式调用函数时,this被绑定到全局对象。
var value = -10;
var myObj = {
value: 0,
increase: function(){
this.value++;
console.log(this.value);
}
};
// this绑定到myObj对象上
myObj.increase(); // var gInc = myObj.increase;
gInc(); // -9 this绑定到window对象上
所以在方法中使用内部函数时要特别注意,下例中other函数中的this并未绑定到myObj对象上
var value = -10;
var myObj = {
value: 0,
increase: function(){
this.value++;
console.log(this.value);
var other = function(){
this.value++;
console.log(this.value);
};
other();// -9, 这时other中的this绑定到window对象上
}
};
// this绑定到myObj对象上
myObj.increase(); // var gInc = myObj.increase;
gInc(); // -8
///////////////
//
//-9
//-8
//-7
幸运的是我们可以使用以下方式来在other中访问myObj对象:
var myObj = {
value: 0,
increase: function(){
this.value++;
console.log(this.value);
var that = this;
var other = function(){
that.value++;
console.log(that.value);
};
other();// -9, 这时other中的this绑定到window对象上
}
};
// this绑定到myObj对象上
myObj.increase(); //
//////////////
//
//
作为浏览器兼容性中很重要的一条:element.attachEvent绑定事件方法,当该事件触发时this指针并未绑定到element对象上,而是绑定到了window对象上,原因在于IE中事件触发时,响应函数是以一个独立函数即函数调用模式来调用的
三、构造器模式调用:
如果在一个函数前面加上new调用则成为构造器模式调用。使用new运算符,会产生一个连接到该函数prototype的新对象,this指针则被绑定到这个新对象上。
var P = function(n){
this.name = n;
}
P.prototype.getName = function(){
console.log(this.name);
}
var p = new P('woodtree'); // 这时P中的this对象呗绑定p指向的对象引用上
p.getName();// woodtree
同时new运算符还会改变函数的返回值。以函数调用模式调用P即P()返回undefined,而通过new运算符则返回一个新对象。new运算符类似于以下Function.prototype.create函数:
var P = function(n){
this.name = n;
}
P.prototype.getName = function(){
console.log(this.name);
}
var p = new P('woodtree');
p.getName();
Object.prototype.create = Object.create || function(proto){
var F = function(){};
F.prototype = proto;
return new F();
}
Function.prototype.create = function(){
var that = object.create(this.prototype);
var obj = this.apply(that, arguments);
return obj || that;
}
var p2 = P.create('hello new');
p2.getName(); // hello new
四、apply、call模式调用:
javascript中函数对象继承自Object亦可以拥有方法。call跟apply允许我们选择this的绑定对象。这两个方法的区别在于apply第二个参数必须是一个数组或者类数组对象即拥有length属性(arguments、NodeList、HTMLElementCollection等),而call除了第一个参数为要绑定this的对象外,后可跟无数的参数,参数之间用逗号间隔。
var P = function(n){
this.name = n;
}
P.prototype.getNameAndAge = function(age){
console.log(this.name + age);
}
P.prototype.getNameAndAge.call({
name: 'catboat'
}, 99);
P.prototype.getNameAndAge.apply({
name: 'lanuch'
}, [99]);
通过使用apply与call方法我们可以自行实现ES5中的bind函数
var P = function(n){
this.name = n;
}
P.prototype.getNameAndAge = function(age, age2){
console.log(this.name + age + age2);
}
P.prototype.getNameAndAge.call({
name: 'catboat'
}, 99);
P.prototype.getNameAndAge.apply({
name: 'lanuch'
}, [99]);
Function.prototype.bindContext = function(that){
var _method = this,
slice = Array.prototype.slice,
args = slice.call(arguments, 1);
return function(){
_method.apply(that, Array.prototype.concat.apply(args, arguments));
}
};
var f1 = P.prototype.getNameAndAge.bindContext({
name: 'barque'
}, 88);
f1(9);
同样我们也可以解决IE中事件触发时,this指针问题(以下代码来自《Javascript框架设计》):
var addEvent = document.addEventListener ? function(el, type, fn, capture){
return el.addEventListener(type, fn, capture);
} : function(el, type, fn){
el.attachEvent('on' + type, fn.bindContext(el, event));
}
javascript中this指针探讨的更多相关文章
- javascript中this指针
看完此片文章豁然开朗,非常感谢.javascript技术难点(三)之this.new.apply和call详解 下面说一说自己的理解: this指针总是指向调用他的对象,其实我更愿意理解为:this指 ...
- 图说js中的this——深入理解javascript中this指针
没搞错吧!js写了那么多年,this还是会搞错!没搞错,javascript就是回搞错! ………… 文章来源自——周陆军的个人网站:http://zhoulujun.cn/zhoulujun/html ...
- javascript中this指针的认识
javascript中上下文环境就是this指针,即被调用函数所处的环境.这个上下文环境在大多数情况下指的是函数运行时封装这个函数的那个对象:当不通过任何对象单独调用一个函数时,上下文环境指的就是全局 ...
- JavaScript中this指针指向的彻底理解
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象 这一点与函数中自由变量Action-varibal不同 var ...
- 彻底理解javascript中的this指针
http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/ https://www.benn ...
- 由javascript中的this指针所想到的
初次结识 this 指针,是在学 <<C++ Primer Plus>>这本书的时候(这本书勉强读了一二遍,之后转学 html+css+js了,不过这是后话). 依稀记得书中举 ...
- 深入认识JavaScript 中的this指针
深入认识JavaScript 中的this指针this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象.在实现对象的方法时,可以使用this指针来获得该对象自身的引用.和传统意义的面向对象 ...
- 从函数调用的角度,探讨JavaScript中this的用法
js函数调用方式大概可分为:函数调用,构造器调用,call或apply,方法调用四种方式.下面结合一些基础概念和实测代码,从函数调用的角度,探讨JavaScript中this的用法. 1. new对函 ...
- <javaScript>谈谈JavaScript中的变量、指针和引用
1.变量我们可能产生这样一个疑问:编程语言中的变量到底是什么意思呢?事实上,当我们定义了一个变量a时,就是在存储器中指定了一组存储单元,并将这组存储单元命名为a.变量a的值实际上描述的是这组存储单元中 ...
随机推荐
- 详解C语言的类型转换
1.自动类型转换 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0-255( ...
- 使用cookie实现计数器功能
思路是:若第一次访问,创建cookie.若访问次数大于一,则先读出cookie值赋给一个值,然后再重新写入cookie. <?php if(!isset($_COOKIE['num'])){ $ ...
- 关于CSS中text-decoration值没有替换而是累积的疑问
做了个实验: <!DOCTYPE html> <html> <head> <title>BaiDuTest.html</title> < ...
- table表格制作
分享一个简单的表格,代码如下: <table border=3 bordercolor=blue align=center cellspacing=3 cellpadding=6> < ...
- Linux 将文件夹下的所有文件复制到另一个文件里
如何将文件夹/home/work下的文件复制到/home/temp里面? 使用命令: cp -R /home/work/* /home/temp *表示所有文件 但是/home/work 下的隐藏文件 ...
- HTML流动布局各种宽度自适应
<!DOCTYPE html> <html lang="en"> <style> html,body{ padding: 0;margin: 0 ...
- 【菜鸟玩Linux开发】Redis安装和自启动配置
Redis是一个C实现的基于内存.可持久化的键值对数据库,在分布式服务中常作为缓存服务.本篇将介绍在CentOS下如何从零开始安装到配置启动服务. 一. 安装Redis Redis的安装其实相当简单, ...
- 阿里云安装Tomcat
1.Apache官方网站下载Tomcat http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.0.35/bin/apache-tomcat-8.0 ...
- block的复习
main.m // // main.m // 8A10.Block的复习 // // Created by huan on 16/2/8. // Copyright © 2016年 huanx ...
- Python基于pandas的数据处理(一)
import pandas as pd, numpy as np dates = pd.date_range(', periods=6) df = pd.DataFrame(np.random.ran ...