js this pointer 指针
this
JavaScript的函数内部如果调用了this,那么这个this到底指向谁?
答案是,视情况而定!
如果以对象的方法形式调用,比如xiaoming.age(),该函数的this指向被调用的对象,也就是xiaoming,这是符合我们预期的。
如果单独调用函数,比如getAge(),此时,该函数的this指向全局对象,也就是window。
坑爹啊! 更坑爹的是,如果这么写:
var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN
也是不行的!要保证this指向正确,必须用obj.xxx()的形式调用!
由于这是一个巨大的设计错误,要想纠正可没那么简单。ECMA决定,在strict模式下让函数的this指向undefined,因此,在strict模式下,你会得到一个错误:
'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
var fn = xiaoming.age;
fn(); // Uncaught TypeError: Cannot read property 'birth' of undefined
这个决定只是让错误及时暴露出来,并没有解决this应该指向的正确位置。
有些时候,喜欢重构的你把方法重构了一下:
'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - this.birth;
}
return getAgeFromBirth();
}
};
xiaoming.age(); // Uncaught TypeError: Cannot read property 'birth' of undefined
结果又报错了!原因是this指针只在age方法的函数内指向xiaoming,在函数内部定义的函数,this又指向undefined了!(在非strict模式下,它重新指向全局对象window!)
修复的办法也不是没有,我们用一个that变量首先捕获this:
'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var that = this; // 在方法内部一开始就捕获this
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - that.birth; // 用that而不是this
}
return getAgeFromBirth();
}
};
xiaoming.age(); // 25
用var that = this;,你就可以放心地在方法内部定义其他函数,而不是把所有语句都堆到一个方法中。
apply
虽然在一个独立的函数调用中,根据是否是strict模式,this指向undefined或window,不过,我们还是可以控制this的指向的!
要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。
用apply修复getAge()调用:
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
另一个与apply()类似的方法是call(),唯一区别是:
apply()把参数打包成Array再传入;
call()把参数按顺序传入。
比如调用Math.max(3, 5, 4),分别用apply()和call()实现如下:
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
对普通函数调用,我们通常把this绑定为null。
装饰器
利用apply(),我们还可以动态改变函数的行为。
JavaScript的所有对象都是动态的,即使内置的函数,我们也可以重新指向新的函数。
现在假定我们想统计一下代码一共调用了多少次parseInt(),可以把所有的调用都找出来,然后手动加上count += 1,不过这样做太傻了。最佳方案是用我们自己的函数替换掉默认的parseInt():
var count = 0;
var oldParseInt = parseInt; // 保存原函数
window.parseInt = function () {
count += 1;
return oldParseInt.apply(null, arguments); // 调用原函数
};
// 测试:
parseInt('10');
parseInt('20');
parseInt('30');
count; // 3
js this pointer 指针的更多相关文章
- Atitit java方法引用(Method References) 与c#委托与脚本语言js的函数指针
Atitit java方法引用(Method References) 与c#委托与脚本语言js的函数指针 1.1. java方法引用(Method References) 与c#委托与脚本语言js ...
- js连续赋值、指针
jq的源码中有很多连续赋值,类似这样的: var a = {n:1}; var b = a; // 持有a,以回查 a.x = a = {n:2}; alert(a.x);// --> unde ...
- 关于JS的This指针
下面讨论一个执行上下文的最后一个属性——this指针的概念. This指针 A this value is a special object which is related with the exe ...
- JS监测鼠标指针位置
需求1:鼠标移入正方形的时候,蓝色小圆点跟随鼠标滚动(不许蓝色小圆点超出正方形区域),正方形里实时显示当前鼠标相对于body的坐标. <!DOCTYPE html> <html la ...
- Pointer 指针
利用指针访问对象,指针指向一个对象,允许使用解引用符(操作符*)来访问对象 int ival = 42; int *p = &ival;//p存放变量ival的内存地址,p是指向变量ival的 ...
- JS中的this指针
1.JS中this指针指向 JS中函数的 this 并不遵守词法作用域规则(即作用域由声明时所处的位置决定),而是取决于函数的调用方式 影响 this 指针的因素有以下: 方法是否由某个对象调用,比如 ...
- Practical Node.js (2018版) 第7章:Boosting Node.js and Mongoose
参考:博客 https://www.cnblogs.com/chentianwei/p/10268346.html 参考: mongoose官网(https://mongoosejs.com/docs ...
- Google V8编程详解(五)JS调用C++
http://blog.csdn.net/feiyinzilgd/article/details/8453230 最近由于忙着解决个人单身的问题,时隔这么久才更新第五章. 上一章主要讲了Google ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
随机推荐
- Linux常见英文报错中文翻译(菜鸟必知)
Linux常见英文报错中文翻译(菜鸟必知) 1.command not found 命令没有找到 2.No such file or directory 没有这个文件或目录 3.Permission ...
- python的类
一.语法 python类的机制是 C++ 的类机制和 Modula-3 的类机制的混合体: 允许多继承的类继承机制,派生类可以重写它父类的任何方法,一个方法可以调用父类中重名的方法: 1.动态特性: ...
- css常用字体
宋体 SimSun 黑体 SimHei 微软雅黑 Microsoft YaHei 微软正黑体 Microsoft JhengHei 新宋体 NSimSun 新细明体 PMingLiU 细明体 Ming ...
- setTimeout 方法带参数传递
setTimeout(callback, after, arg1, arg2); 其中,callback即function(){},after为时间参数,指多久后执行callback,单位为毫秒,30 ...
- Java笔试基础01
单例模式主要作用是保证在Java应用程序内,一个类只有一个实例存在. 手写单例 1.较为安全的写法 public class Singleton01{ private static Singleton ...
- python 字体颜色的设置
实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27 ...
- 超酷的Prezi在线ppt制作网站
prezi.com 你还在用office Power Point 制作PPT吗? 使用prezi.com制作ppt试试.http://prezi.com/explore/staff-picks/
- jQuery id模糊 选择器 批量处理
$("span[id^='province_']").each(function(index,obj){ $(obj).bind("click", ...
- HTML5 Canvas ( 文字的书写和样式控制 ) font, fillText, strokeText
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- sql 数据库修复
数据库修复 exec sp_dboption 'dbname1','single user',‘true’ dbcc checkdb('dbname1') dbcc checkdb('dbname1' ...