理解javascript this 值
如何确定this的值
this值会被传递给所有函数,this的值是基于运行时调用函数的上下文。
例如:从全局作用域调用sayFoo函数时,this引用window对象
当它作为myObject的一种方法调用时,this引用myObject
var foo = "foo";
var myObject = { foo: "I am myObject.foo" };
var sayFoo = function () {
console.log(this.foo);
};
//给myObject设置一个sayFoo属性,并指向sayFoo函数
myObject.sayFoo = sayFoo;
myObject.sayFoo();//输出 I am myObject.foo
sayFoo(); //输出foo
在嵌套函数中用this关键字引用head对象
当在嵌套函数内部使用this时,在ES3中,this失去了方向,引用的是head对象
例如:func2和func3内部的this失去了方向,引用的不是myObject,而是head对象
当匿名函数在函数内部被调用时,匿名函数内的this值将是head对象
例如:
var foo = {
func1: function(bar) {
bar(); //输出window,而不是foo
console.log(this); //这里的this关键字是foo对象的一个引用
}
};
foo.func1(function() {
console.log(this);
});
当this值得宿主函数被封装在另外一个函数内部或在另一个函数的上下文中被调用时,this值将永远是对head对象的引用。
var myObject = {
func1: function() {
console.log(this); //输出myObject
var func2 = function() {
console.log(this); //输出window,从此处开始,this都是window对象了
var func3 = function () {
console.log(this);//输出window,即head对象
}();
}();
}
};
myObject.func1();
充分利用作用域链研究嵌套函数问题
可以简单的在父函数中使用作用域链来保留对this的引用,以便this值不
丢失。如下代码演示通过 that变量以及其作用域来有效的跟踪函数上下文:
//充分利用作用域链研究嵌套函数问题
var myObject = {
myProperty:"I can see the light",
myMethod: function() {
var that = this; //myMethod作用域内,保存this引用(也就是myObject)
var helperFunction = function() { //子函数
//输出通过作用域链得到“I can see the light”
console.log(that.myProperty);
console.log(this.myProperty);
console.log(this);
}();
}
};
myObject.myMethod();//调用myMethod
使用call()或apply()控制this值
this值通常取决于调用函数的上下文,但是我们可以使用apply()或call()来重写/控制this值
call()和apply()的区别在于函数传递参数的方式不同
如果使用call(),参数只是用逗号分隔的值
如果使用apply(),参数值以数组的形式传递。
例如如下:通过 call调用函数,以便使函数内部的this值将myObject作为它的上下文
//使用call()或apply()控制this值
var myObject = {};
var myFunction = function(parm1, parm2) {
//调用函数的时候,通过call()将this指向myObject
this.foo = parm1;
this.bar = parm2;
console.log(this);
};
myFunction.call(myObject, "foo", "bar");//调用函数,设置this值引用到myObject
console.log("foo=" + myObject.foo + ",bar=" + myObject.bar); //输foo=foo,bar=bar
改为直接调用的结果为:
var myObject = {};
var myFunction = function(parm1, parm2) {
//调用函数的时候,通过call()将this指向myObject
this.foo = parm1;
this.bar = parm2;
console.log(this);
};
myFunction("foo", "bar");//直接调用,this指向window
console.log("foo=" + myObject.foo + ",bar=" + myObject.bar);//foo=undefined,bar=undefined
console.log("foo=" + myFunction.foo + ",bar=" + myFunction.bar);//foo=undefined,bar=undefined
console.log("foo=" + foo + ",bar=" + bar);//foo=foo,bar=bar
在用户自定义构造函数内部使用this关键字
使用new关键字调用函数时,this值(在构造函数中声明的)引用实例本身。
例如:如下代码创建了Person构造函数,创建Person的实例时,this.name将引用新创建的对象。
var Person = function(name) {
this.name = name || "john doe";//this引用所创建的实例
};
var cody = new Person("Cody Lindley");//基于Person构造函数创建实例
console.log(cody.name);//输出Cody Lindley
使用new关键字调用构造函数时,this引用“即将创建的对象”
如果不使用new关键字,this值将是调用Person的上下文—在本例中是head对象
如下代码:
var Person2 = function (name) {
this.name = name || "john doe"; //this引用所创建的实例
};
var cody2 = Person2("Cody Lindley"); //基于Person构造函数创建实例
console.log(cody2.name); //报name不存在,实际上name值设置到了window.name上
console.log(window.name); //输出Cody Lindley
原型方法内的this关键字引用构造函数实例
当在添加至构造函数的prototype属性的函数中使用this时,this引用调用方法的实例:
例如:
//原型方法内的this关键字引用构造函数实例
var Person = function(x) {
if (x) {
this.fullName = x;
}
};
Person.prototype.whatIsMyName = function() {
return this.fullName;//this引用Person()所创建的实例上
};
var cody = new Person("cody lindley");
var lisa = new Person("lisa lindley");
//调用继承的whatIsMyName方法,该方法用this引用实例
console.log(cody.whatIsMyName(), lisa.whatIsMyName()); //输出cody lindley,lisa lindley
Object.prototype.fullName = "John Doe";
var john = new Person();
console.log(john.whatIsMyName());
当在prototype对象中的方法内部使用this关键字时,this可用于引用实例。如果该实例不包含所要查找的属性,则继续在原型上查找。
理解javascript this 值的更多相关文章
- 深入理解JavaScript系列(19):求值策略(Evaluation strategy)
介绍 本章,我们将讲解在ECMAScript向函数function传递参数的策略. 计算机科学里对这种策略一般称为“evaluation strategy”(大叔注:有的人说翻译成求值策略,有的人翻译 ...
- 深入理解JavaScript运行机制
深入理解JavaScript运行机制 前言 本文是写作在给团队新人培训之际,所以其实本文的受众是对JavaScript的运行机制不了解或了解起来有困难的小伙伴.也就是说,其实真正的原理和本文阐述的并不 ...
- 深入理解javascript系列(4):立即调用的函数表达式
本文来自汤姆大叔 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行. 在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法 ...
- 深入理解JavaScript的闭包特性如何给循环中的对象添加事件
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...
- 深入理解javascript原型和闭包(1)——一切都是对象
“一切都是对象”这句话的重点在于如何去理解“对象”这个概念. ——当然,也不是所有的都是对象,值类型就不是对象. 首先咱们还是先看看javascript中一个常用的函数——typeof().typeo ...
- 深入理解javascript原型和闭包(3)——prototype原型
既typeof之后的另一位老朋友! prototype也是我们的老朋友,即使不了解的人,也应该都听过它的大名.如果它还是您的新朋友,我估计您也是javascript的新朋友. 在咱们的第一节(深入理解 ...
- 深入理解javascript原型和闭包(4)——隐式原型
注意:本文不是javascript基础教程,如果你没有接触过原型的基本知识,应该先去了解一下,推荐看<javascript高级程序设计(第三版)>第6章:面向对象的程序设计. 上节已经提到 ...
- 深入理解javascript原型和闭包(5)——instanceof
又介绍一个老朋友——instanceof. 对于值类型,你可以通过typeof判断,string/number/boolean都很清楚,但是typeof在判断到引用类型的时候,返回值只有object/ ...
- 深入理解javascript原型和闭包(8)——简述【执行上下文】上
什么是“执行上下文”(也叫做“执行上下文环境”)?暂且不下定义,先看一段代码: 第一句报错,a未定义,很正常.第二句.第三句输出都是undefined,说明浏览器在执行console.log(a)时, ...
随机推荐
- Hadoop相关资料
http://blog.csdn.net/skywalker_only/article/details/40650427
- 在Ubuntu下编译FFmpeg
第一步:准备编译环境 .tar.bz2 -2245/ ./configure --enable-static--enable-shared--prefix=/usr/localmakesudomake ...
- 开源项目之easyrtmp
https://github.com/bigbluebutton86/EasyRTMP/tree/master/src http://dl.linux-sunxi.org/SDK/A20/A20_SD ...
- Spring Cloud 微服务五:Spring cloud gateway限流
前言:在互联网应用中,特别是电商,高并发的场景非常多,比如:秒杀.抢购.双11等,在开始时间点会使流量爆发式地涌入,如果对网络流量不加控制很有可能造成后台实例资源耗尽.限流是指通过指定的策略削减流量, ...
- drupal7 使用(hook_preprocess_HOOK)向各个主题模版里面传递变量
函数地址:hook_preprocess_HOOK 1 首先解释下hook_preprocess_HOOK这个钩子的含义: hook _ preprocess _ H ...
- GUN C中的错误报告
在C语言中,很多库函数在调用失败时都会返回特定的值.比如返回-1,空指针,EOF等.但是这些值仅仅表示的调用失败,并未给出详细的错误信息.如果想查看详细的错误内容,就要去查看errno的错误代码,er ...
- php之 人员的权限管理
1.想好权限管理的作用? 2.有什么权限内容? 3.既然有权限管理那么就会有管理员? 4.登录后每个人员的界面会是不一样的? 一.想好这个权限是什么? 就做一个就像是vip的功能,普通用户和vip用户 ...
- 字符串HASH模板
//注意MAXN是最大不同的HASH个数,一般HASHN是MAXN的两倍左右,MAXLEN表示字符串的最大长度 //K表示正确率,越大正确率越高,当时也越费空间,费时间. //使用前注意初始化hash ...
- SimpleDateFormat注意点
今天测试了一下SimpleDateFormat把一个字符串转为Date类型 SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-M ...
- IntelliJ IDEA集成JProfiler,入门教程
说明: JProfiler是用于分析J2EE软件性能瓶颈并能准确定位到Java类或者方法有效解决性能问题的主流工具,它通常需要与性能测试工具如:LoadRunner配合使用,因为往往只有当系统处于压力 ...