【笔记】探索js 的this 对象 (第一部分)
最近在看 你不知道的javascript 这本书,在第二部分看到了一个比较重要的知识点 那就是 this对象的全面认识,于是做一下笔记
博主本人在看这本书之前也一直以为 this 是指一切引用类型的本身 但直到最近才明确了 this 对象的见解 关于this 对象误解书上也作了一些解释 下面我来整理一下
先看下面的例子:
function foo(num){
console.log(num);
this.count++;
}
foo.count = 0;for (var i = 0; i < 10; i++) {
if (i > 5) {
foo(i);
}
}
console.log("函数被调用了多少次?" + foo.count); //0
在js 里面 函数即对象 我们将foo 函数定义了a 属性,在循环调用 foo函数中 foo函数的a 属性自增1
但是为什么最后输出结果为0 ???
这就是我们对this 对象的第一个误解:this指向函数自身
实际上this.a 指向了 window对象,不相信??看看下面代码的变化吧
function foo(num){
console.log(num);
this.count++;
}
foo.count = 0;
window.count = 0; window.count 还没有被初始化
for (var i = 0; i < 10; i++) {
if (i > 5) {
foo(i);
}
}
console.log("函数被调用了多少次?" + foo.count); //
console.log("count 属性变成了 window属性了!!但window属性并没有初始化:" + window.count); //NaN
打开你的编译器试试便知晓~
函数的执行 this.count 并没有指向 foo函数的本身而是当 foo函数循环执行的时候为 window对象 添加 count属性 并且每次循环为这个属性自增1
但是因为 window对象中 并没有count 这个属性所以输出的只是 NaN 的结果
那么我们可以把window.count属性初始化一下
function foo(num){
console.log(num);
this.count++;
}
foo.count = 0;
window.count = 0;
for (var i = 0; i < 10; i++) {
if (i > 5) {
foo(i);
}
}
console.log("函数被调用了多少次?" + foo.count); //
console.log("count 属性变成了 window属性了!!而且window属性得到了初始化:" + window.count);//调用次数为
初始化之后我们就可以看到函数的正确调用次数结果了~
我们再看看第二个误区:
我们对this 对象的第二个误解:this对象指向函数的作用域
看看下面例子:
window.a = "i'm window";
function fun(){
var a = "this is fun";
this.bar();
}
function bar(){
console.log(this.a);
}
fun();// i'm window
bar.call(window);//上面的行为等价于这个
解释一下:
作者在书上的原意是 想把bar 的执行引用绑定在fun 函数中
但是因为 fun是在 window对象下执行的 所以this对象 指向的是 window对象
所以 this.bar() 变成了在window对象下执行函数 bar(),或直接等于在 window 对象下直接调用了 bar() 这个函数
此行为也等价于 bar.call(window)
当然要让bar 函数在fun 函数里面调用何必要花那么大的功夫
直接将bar()函数写在 fun中就可以了
另外声明一点就是:this 对象不指向函数的词法作用域(详情请看 你不知道的javascript 闭包和作用域的一章)
小结:
那么this 的对象指的是哪一个呢?
看了上面的两个例子,我们不难发现this 对象大多数都和 window对象有关系 那是为什么呢?
再举个例子:
function fun(){
this.a = "i'm function fun";
console.log(this.a);
}
fun();//i'm function fun
console.log(window.a);//i'm function fun
表面上看 在fun函数内部定义了 this.a 这一条语句就是给fun 函数添加了一个a 属性
但是当fun 函数执行的时候 实际上却将a 这个属性赋值给了 window对象
因此在下一句里面输出 window.a 的结果 和执行fun 函数的结果一样
归根结底就是因为 fun 函数在 window对象下调用了!
再看一个例子:
function foo(){
console.log(this.a);
}
function fun(){
this.a = "i'm function fun";
console.log(this.a);
}
var obj = {
a: "hello i'm a obj",
foo: foo,
fun: fun
}
obj.foo();//hello i'm a obj
obj.fun();//i'm function fun
这里定义了一个对象字面量 obj
为obj 设置了一个属性 a,值为:"hello i'm a obj"
然后又定义了两个引用属性:foo 和 fun,他们分别引用 foo函数 和 fun函数
当通过obj 调用 foo函数的时候 输出结果是obj 的a属性值
但调用fun 函数的时候输出结果却是函数内部定义的 a属性值
为什么呢??不是说this 不指向函数本身吗???
-------分隔线-------
别混淆了
上面已经说过 函数里面通过this定义的属性并不是属于函数的作用域的
即这个属性并不是函数本身的(虽说js 的函数也是对象 但不带这么玩)
实际上 fun 函数里面的 this.a 这个语句是为函数当前调用环境对象的属性赋值的语句
通俗的说:
如果,fun函数在 obj 里面调用 this.a 语句就为 obj 对象里面的a 属性赋值
如果,fun函数在 window 对象里面调用 this.a 语句就为 window对象里面的 a属性赋值
如果调用函数的环境下没有匹配的属性 就为其环境创建一个属性并赋值
所以我们得出总结:
this 对象指向的是函数执行作用域的对象,即函数在哪里执行,this 对象就指向那里!
如果上面的代码你觉得啰嗦,直接记住这一点就好
【笔记】探索js 的this 对象 (第一部分)的更多相关文章
- 【笔记】探索js 的this 对象 (第三部分)
了解完函数的调用区域是如何影响this 对象的,还有this 的各种绑定方式以及各种绑定方式的优先级后 最后一部分,来了解一下this 的一些例外情况 1.被忽略的this 例如在使用bind 方法时 ...
- 【笔记】探索js 的this 对象 (第二部分)
了解this 对象之后 我们明白了this 对象就是指向调用函数的作用域 那么接下来我们便要清除函数究竟在哪个作用域调用 找到调用的作用域首先要了解一下几点: 1.调用栈: 调用栈就是一系列的函数,表 ...
- 读书笔记-你不知道的JS上-对象
好想要对象··· 函数的调用位置不同会造成this绑定对象不同.但是对象到底是什么,为什么要绑定他们呢?(可以可以,我也不太懂) 语法 对象声明有两个形式: 1.字面量 => var obj = ...
- 超全面的JavaWeb笔记day03<JS对象&函数>
1.js的String对象(****) 2.js的Array对象 (****) 3.js的Date对象 (****) 获取当前的月 0-11,想要得到准确的月 +1 获取星期时候,星期日是 0 4.j ...
- 4月5日--课堂笔记--JS内置对象
JavaScript 4.5 一. JS内置对象 1.数组Array a)创建语法1:var arr=new Array(参数); i. 没有参数:创建一个初始容量为0的数组 ii. ...
- Node.js学习笔记(四): 全局对象
在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性. 这 ...
- 5月15日上课笔记-js中 location对象的属性、document对象、js内置对象、Date事件对象、
location的属性: host: 返回当前主机名和端口号 定时函数: setTimeout( ) setInterval() 二.document对象 getElementById(); 根据ID ...
- web前端学习(四)JavaScript学习笔记部分(6)-- js内置对象
1.JS内置对象-什么是对象 1.1.什么是对象: JavaScript中的所有事物都是对象:字符串.数值.数组.函数 每个对象带有属性和方法 JavaScript允许自定义对象 1.2.自定义对象: ...
- [Effective Java 读书笔记] 第二章 创建和销毁对象 第一条
第二章 创建和销毁对象 第一条 使用静态工厂方法替代构造器,原因: 静态工厂方法可以有不同的名字,也就是说,构造器只能通过参数的不同来区分不同的目的,静态工厂在名字上就能表达不同的目的 静态工厂方法 ...
随机推荐
- Go语言建立一个最简单的服务端点
handlers/handlers.go package handlers import ( "encoding/json" "net/http" ) func ...
- Java学习笔记(八)——java多线程
[前面的话] 实际项目在用spring框架结合dubbo框架做一个系统,虽然也负责了一块内容,但是自己的能力还是不足,所以还需要好好学习一下基础知识,然后做一些笔记.希望做完了这个项目可以写一些dub ...
- 轻松学习LINUX系列教程推出
本系列多媒体教程已完成的博文: 1.轻松学习Linux之入门篇 http://chenguang.blog.51cto.com/350944/449214 2.轻松学习Linux之本地安装系统 (分区 ...
- ubuntu使用命令更新ubuntu系统
我们都知道ubuntu是一款linux系统,它不像WINDOWS系统,它是一个开源的系统,它随时都在更新它系统,所以人们都说Linux系统要比WINDOWS系统安全.为了我们电脑安全,我们如何利用ub ...
- codeforces 某套题s : surf(贪心 || 动态规划)
题目: Now that you’ve come to Florida and taken up surfing, you love it! Of course, you’ve realized th ...
- CSS3盒模型——box-sizing
box-sizing盒模型是CSS3的一个重要属性之一,常常被很多人给忽略了!CSS3出现之前box-sizing盒模型默认的宽高是指内容的宽高,css3之后可以用box-sizing来指定宽高. 目 ...
- Linux操作命令(二)
本次实验将介绍 Linux 命令中 mkdir.rm.mv.cp.cat.nl 命令的用法. 1.mkdir mkdir命令用来创建指定名称的目录,要求创建目录的用户在当前目录中具有写权限,并且指定的 ...
- BestCoder Round #65 (ZYB's Premutation)
ZYB's Premutation Accepts: 220 Submissions: 983 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- BZOJ 2084 [Poi2010]Antisymmetry(manacher)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2084 [题目大意] 对于一个01字符串,如果将这个字符串0和1取反后, 再将整个串反过 ...
- mybatis批量update,返回行数为-1
mybatis批量更新返回结果为-1,是由于mybatis的defaultExExecutorType引起的, 它有三个执行器:SIMPLE 就是普通的执行器:REUSE 执行器会重用预处理语句 ...