最近在看 你不知道的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 对象 (第一部分)的更多相关文章

  1. 【笔记】探索js 的this 对象 (第三部分)

    了解完函数的调用区域是如何影响this 对象的,还有this 的各种绑定方式以及各种绑定方式的优先级后 最后一部分,来了解一下this 的一些例外情况 1.被忽略的this 例如在使用bind 方法时 ...

  2. 【笔记】探索js 的this 对象 (第二部分)

    了解this 对象之后 我们明白了this 对象就是指向调用函数的作用域 那么接下来我们便要清除函数究竟在哪个作用域调用 找到调用的作用域首先要了解一下几点: 1.调用栈: 调用栈就是一系列的函数,表 ...

  3. 读书笔记-你不知道的JS上-对象

    好想要对象··· 函数的调用位置不同会造成this绑定对象不同.但是对象到底是什么,为什么要绑定他们呢?(可以可以,我也不太懂) 语法 对象声明有两个形式: 1.字面量 => var obj = ...

  4. 超全面的JavaWeb笔记day03<JS对象&函数>

    1.js的String对象(****) 2.js的Array对象 (****) 3.js的Date对象 (****) 获取当前的月 0-11,想要得到准确的月 +1 获取星期时候,星期日是 0 4.j ...

  5. 4月5日--课堂笔记--JS内置对象

    JavaScript 4.5 一.    JS内置对象 1.数组Array a)创建语法1:var arr=new Array(参数); i.       没有参数:创建一个初始容量为0的数组 ii. ...

  6. Node.js学习笔记(四): 全局对象

    在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性. 这 ...

  7. 5月15日上课笔记-js中 location对象的属性、document对象、js内置对象、Date事件对象、

    location的属性: host: 返回当前主机名和端口号 定时函数: setTimeout( ) setInterval() 二.document对象 getElementById(); 根据ID ...

  8. web前端学习(四)JavaScript学习笔记部分(6)-- js内置对象

    1.JS内置对象-什么是对象 1.1.什么是对象: JavaScript中的所有事物都是对象:字符串.数值.数组.函数 每个对象带有属性和方法 JavaScript允许自定义对象 1.2.自定义对象: ...

  9. [Effective Java 读书笔记] 第二章 创建和销毁对象 第一条

    第二章  创建和销毁对象 第一条 使用静态工厂方法替代构造器,原因: 静态工厂方法可以有不同的名字,也就是说,构造器只能通过参数的不同来区分不同的目的,静态工厂在名字上就能表达不同的目的 静态工厂方法 ...

随机推荐

  1. html5 -audio-移动端如何自动播放

    最近在做一些活动类页面或者类似于易企秀类型的轻应用经常遇到关于audio标签的应用,对于audio相关的常用知识点以及一些相关的问题如下: <audio id="audios" ...

  2. 【UI】自动化用例设计技巧

    需要封装的方法: 公共的操作方法 经常使用的步骤:超过两次以上 经常使用的组件:输入框.文本框.列表 经常操作的布局:多个组件组成通用的布局 经常操作的页面:ui页面由一个一个单独Activity组成 ...

  3. Java学习笔记(十二)——eclipse和SVN配置,导入SVN服务器项目

    [前面的话] 北京的天气外加自己的不小心终于病了,在病的过程中,感觉身体好着真好,可以学习,可以吃好吃的,可以去运动,这一病了,干什么都感觉没有力气,身体好着真好. 这个文章的背景是:领导把项目最开始 ...

  4. DotNetCore 微服务上传附件

    后台接口升级成netcore 2.0了,然后之前的上传图片的接口就不再使用了.新的接口形式 #region IFormCollection /// <summary> /// IFormC ...

  5. [水煮 ASP.NET Web API2 方法论](12-2)管理 OData 路由

    问题 如何控制 OData 路由 解决方案 为了注册路由,可以使用  HttpConfigurationExtension 类中 MapODataServiceRoute 的扩展方法.对于单一路由这样 ...

  6. 四:Ionic Framework不支持Android4.2.2的解决方法

    目前有一个项目是在Ionic3上开发的,浏览器中进行开发和处理,并将项目打包至Android7.1的平板中查看,运行效果是不错的 大体的框架与交互方式已经完成了,开会时并演示给用户看,发现都是不错的, ...

  7. Android使用UncaughtExceptionHandler捕获全局异常

    Android系统的“程序异常退出”,给应用的用户体验造成不良影响.为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理.通过Thread.setDe ...

  8. IEDA快捷键

    前言 开发工具从eclipse过渡到idea了:在刚开始使用的时候被idea强大的快捷键都惊呆了,这里记录了常见的一些快捷键和小伙伴们分享. 快捷键 鼠标悬停在单词上自动提示 : settings-- ...

  9. Mixins 改成使用高阶组件调用

    把组件放在另外一个组件的 render 方法里面, 并且利用了 {...this.props} {...this.state} 这些  JSX 展开属性 对比下2种代码: 原始方式: <!DOC ...

  10. 【uva 10294】 Arif in Dhaka (First Love Part 2) (置换,burnside引理|polya定理)

    题目来源:UVa 10294 Arif in Dhaka (First Love Part 2) 题意:n颗珠子t种颜色 求有多少种项链和手镯 项链不可以翻转 手镯可以翻转 [分析] 要开始学置换了. ...