JavaScript this 的理解
来源:互联网 发布:加内特2004季后赛数据 编辑:程序博客网 时间:2024/05/17 06:21
this 对象是在运行时基于函数的执行环境绑定的:在全局函数中,this 等于 window,而当函数被视为某个对象的方法时,this 等于这个对象。不过匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window
(function() { console.log(this === window); // true })();
每个函数在被调用的时候都会自动取得两个特殊的变量,this 和 argument ,内容函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远无法访问外部函数中的这两个变量。
this 的指向总体可以分为四种情况:
1. 直接调用
2. 作为函数对象方法调用
3. 构造函数调用
4. call 跟 apply 方法调用
- js 中 this 在函数定义的时候是确定不了的,只有在函数运行的时候才能确定。
- 如果一个函数中有 this,但是它没有被上一级的对象所调用,那么 this 指向的就是 ==window==
- 如果一个函数中有 this,这个函数有被上一级的对象所调用,那么 this 指向的就是==上一级的对象==
- 如果一个函数中有 this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用的,this 指向的也只是它的上一级的对象。
- 如果返回值是一个对象,那么 this 指向的就是那个返回的对象,如果返回值不是一个对象,那么 this 还是指向函数的实例。
- javascript 中 function 也是对象,window 是全局变量
this 的指向是不可以改变的,如下:
var obj = { name: "xiaoming" } function getName() { this = obj; console.log(this.name); } getName(); // 运行报错
var name = "global"; var obj = { name: "local", getName: function() { return function() { // 该匿名函数为闭包 return this.name; // 返回的是? }; } }; console.log(obj.getName());
这个答案当然是 “global” 。因为我们知道每个函数在调用的时候会获取两个对象:this和arguments。而内部函数在搜索这个两个对象时只会搜索到其活动对象为止。而匿名函数的执行环境具有全局性,所以这个this就指向了全局window。
如果需要访问匿名函数外部变量
var name = "global"; var obj = { name: "local", getName: function() { var that = this; return function() { return that.name; // local }; } }; console.log(obj.getName());
不可以改变 this 的值,但可以把 this 用变量存储起来,这样 this 的指向就不会变了
js 中的 call 方法
function hello(con){ alert(this + " " + con);}hello.call("hello","world");//弹出 hello world
call() 的用法
1. 把第二个到最后一个参数当作函数执行时传入的参数
2. 把函数执行时的 this 指向第一个参数
3. 执行函数
js 执行函数的时候会默认执行以上的操作,即执行函数操作 func()
相当于 fun.call(window,p1,...);
ES5 中有三种函数调用形式:
func(p1,p2...)obj.child.method(p1,p2)func.call(context,p1,p2);
如果传的 context 是 null 或 undefined ,那么 window 对象就是默认的 context (严格模式下默认 context 是 undefined)。
第三种,才是正常的调用形式。
例如:
func(p1,p2); 等价于 func.call(undefined,p1,p2)obj.child.method(p1,p2) 等价于 obj.child.method.call(obj.child,p1,p2)
[] 语法:
function fn (){ console.log(this) }var arr = [fn, fn2]arr[0]() //这里面的 this 又是什么呢?
我们可以把 arr0 想象成 arr.0() ,虽然后者有语法错误,但是形式与转换代码里的 obj.child.method(p1,p2) 对应上了,于是就可以转换了
arr[0]() 假象为 arr.0() 然后转换为 arr.0.call(arr)那么里面的 this 就是 arr 了
总结
1. this 就是 call 一个函数时,传进去的 context
2. 如果你的函数调用形式不是 call 形式,则可转换为 call 形式。
实例一:
function a(){ var user = "gray"; alert(this.user); //undefined alert(this); //window}a();
a() 相当于 window.a(), 或 a.call(undefined),window 中并没有定义 user,因此是 undefined
实例二:
var a= { user:"gray", fn:function(){ alert(this.user); }};a.fn(); //gray
相当于 window.a.fn() 或a.fn.call(a),这里用到了第三条规则,fn 被上一级对象 a 调用,因此 this 指向的对象 a。
实例三:
var a= { user:"gray", fn:function(){ alert(this.user); }};var b = a.fn;b(); //undefined
this 永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用过的。此处 b 只是指向 a.fn,并没有执行该函数,而 this 是在执行时才能确定指向的,因此,真正执行的 b() 相当于 window.b() ,或者 b.call() 所以 this 指向 window。
==实例 四:==
针对第四条规则,查看以下例子
var o = { a:10, b:{ // a:12, fn:function(){ console.log(this.a); //undefined } }}o.b.fn();
尽管对象 b 中没有 a 属性,这个 this 指向的也是对象 b,因为 this 只会指向它的上一级对象,不管这个对象中有没有 this 所要访问的属性。此例中,b 中虽然可以读到 a 的值,但是 b 没有 a 属性,所以 this.a 为 undefined
构造函数 this
function Fn(){ this.user = "GC";}var a = new Fn();console.log(a.user); //GC
new 操作符做四件事:
1. 创建一个新的对象2. 将构造函数的作用域赋给了新的对象(因此 this 指向了该对象)3. 执行构造函数的代码(为这个新对象添加属性)4. 返回新对象。
这里之所以对象 a 可以点出函数 Fn 里面的 user ,是因为 ==new 关键字可以改变 this 的指向==,将这个 this 指向对象 a,这里是说 a 是对象,因为用了 new 关键字就是创建了一个对象实例,这里用变量 a 创建了一个 Fn 的实例(相当于复制了一份 Fn 到对象 a 里面),此时仅仅只是创建,没有执行,而调用这个函数的是对象 a,那么为什么对象 a 中会有 user ,因为已经复制了一份 Fn 函数到对象 a 中,用了 new 关键字就等同于复制了一份。
为什么 this 会指向 a ?首先 new 关键字会创建一个空对象,然后会自动调用一个 apply 方法,将 this 指向这个空对象,这样的话,函数内部的 this 就会被这个空的对象替代。
## 当函数有返回值
实例一:
function fun(){ this.user = "gray"; return 1;}var f = new fun();alert(f.user); //gray
实例二:
function fun(){ this.user = "gray"; return {};}var f = new fun();alert(f.user); //undefined
实例三:
function fn() { this.user = 'gray'; return function(){};}var a = new fn; console.log(a.user); //undefined
实例四:
function fn() { this.user = 'gray'; return undefined;}var a = new fn; console.log(a.user); //gray
还有一点,虽然 null 也是对象,但这里 this 还是指向那个函数的实例
实例五:
function fn() { this.user = 'gray'; return null;}var a = new fn; console.log(a.user); //gray
比较上述几个例子,如果返回值是一个对象,那么 this 指向的就是那个返回的对象,如果返回值不是一个对象,那么 this 还是指向函数的实例。
注意:
1. 在严格模式下,默认的 this 不是 window ,而是 undefined
- Javascript this的理解
- JavaScript this 的理解
- 理解 JavaScript 的 this 关键字
- 理解 JavaScript 的 this 关键字
- coffeescript(javascript) this 的理解
- 对javascript的this理解
- JavaScript 对this的理解
- javascript对this的理解
- JavaScript中this的理解
- 【javascript】javascript中this关键字的理解
- javascript的this关键字的理解
- JavaScript中的this的深入理解
- 理解 JavaScript 的 this 关键字(代码)
- Javascript中this、prototype、constructor的理解
- JavaScript 嵌套函数中this的理解
- Javascript之this关键字的深入理解
- Javascript中this、prototype、constructor的理解
- Javascript中this、prototype、constructor的理解
- Excuses, Excuses!
- [BZOJ1061][NOI2008]志愿者招募 费用流
- 基本文件操作&fopen函数&FILE指针&ftell &fseek&rewind&fgets文件复制&feof
- EM算法(期望最大化)——理论部分
- 各种排序方法的c++实现
- JavaScript this 的理解
- effective java 读书笔记---第7章 方法
- [省选] [线段树] [差分数组] [BZOJ1558] [JSOI2009] 等差数列
- Linux下mysql备份
- Java学习笔记 Day04 (for循环嵌套、函数以及函数重载、数组)
- 排序算法01:冒泡排序
- springBoot发送邮件
- 【C++学习笔记】if条件分支
- 将二叉树拆成链表