文档章节

javascript的this简单记忆

x
 xinshijue6080
发布于 2017/02/16 17:48
字数 1009
阅读 1
收藏 0
点赞 0
评论 0

一直感觉javascript中的this是一个大坑,虽然一直都有注意,一直都有研究,但是总是会忘记。在这里,总结一下一些简单的规律

不考虑箭头函数的情况下

下面的所有的都是不考虑箭头函数的情况下,因为箭头函数和普通的差别很大

直接调用的都是window

除非是bind绑定过的,其他情况下,直接调用的方法的this都是window。所谓的直接调用,就是直接以method()的形式调用,没有call, apply, new

看几种情况:

function foo(){
   return this;
}
foo(); // window
var obj = {
  foo: function(){ return this; }
}

var foo = obj.foo;
foo(); // window
function Foo(){
  this.foo = function(){
    console.log(this);
  }

  var foo = this.foo;
  foo(); // window
}

new Foo();

谁调用,谁是this

除非是bind绑定过的,一般情况下,谁调用这个方法,那么内部的this就指向这个对象。新视觉影院也就是obj.method(),那么就指向objobj.foo.method(),那么就指向obj.foo

看几个例子:

var obj = {
  foo: function(){ return this; }
}
obj.foo(); // obj调用,所以结果是obj
function foo(){ return this };
var obj = {};
obj.foo = foo;
obj.foo(); // obj调用,所以结果是obj
var obj = {
  bar: function(){ return this; },
  foo: function(){
    return this.bar();
  }
}
obj.foo(); // 在foo中, this是obj, 而this调用的bar, 所以返回的是obj
var obj = {
   bar: {
     foo: function(){ return this }
   }
}
obj.bar.foo(); // obj.bar调用的foo,所以返回的结果是bar
function foo(){
  this.bar = function(){ return this }
  return this.bar();
}
foo(); // 由于foo中的this是window, 所以this.bar()返回的是window
function Foo(){
  this.foo = function(){ console.log(this); }
  this.foo();
}
var object = new Foo(); // 由于this.foo中的this是object,所以this是object

new会生成一个新的this

所有情况下,(箭头函数不能使用new关键字),使用了new以后,会把内部的this指向新生成的对象。

除去bind的情况下prototype中的this也指向新生成的对象

function Foo(){
  console.log(this); // this指向新生成的对象,object
}
var object = new Foo(); 
function Foo(){
  this.foo = function(){ return this === object; }
}
var object = new Foo();
object.foo(); // 输出true
function Foo(){}
Foo.prototype.foo = function(){ return this === object; }
var object = new Foo();
object.foo(); // 输出true

call, apply是谁,this就是谁

除非是bind的情况call, apply是谁,那么内部的this就是谁。

注意:如果是基本类型,那么javascript会把基本类型转换成Object的形式

也是看例子:http://www.052260.org/

function foo(){ return this; }
foo.call("a"); // String
typeof foo.call("a"); // object
var obj = {
  foo : function(){ return this; }
}
obj.foo.call(1); // Number
typeof obj.foo.call(1); // object
function Foo(){
  this.foo = function(){ return this; }
}
var object = new Foo();
object.foo.call(1); // Number

bind是谁,this就是谁

除了new这一种特殊情况bind的对象是谁,那么this也就是谁。即使call, apply也没有权利改变。

注意:如果是基本类型,那么javascript会把基本类型转换成Object的形式

function foo() { return this; } 
foo = foo.bind(1);
foo(); // Number
typeof foo(); // object
function foo() { return this; } 
foo = foo.bind(1);
foo.call("a"); // Number 1
function Foo() { return this; } 
Foo.prototype.foo = (function(){ return this; }).bind(1);
var object = new Foo();
object.foo(); // Number

特殊情况
new这个关键词可以改变方法内部的this,使他指向新生成的对象

function Foo(){ this.foo = function(){ console.log(this === obj) } }
Foo = Foo.bind(1);
var obj = new Foo();
obj.foo(); // 输入true

箭头函数

箭头函数的this是根据定义环境的this来定的,也就是说定义的函数周围的this是什么,它的this就是什么。

而且不会被bind, call, apply所改变

var foo = ()=>{ return this };
foo() // window
var obj = { foo: ()=>this }
obj.foo(); // 由于定义的时候,周围的环境是window,所以返回window
var obj = {
  foo(){
     var bar= ()=>{ return this };
     return bar();
  }
}
obj.foo(); // 由于定义bar的时候,周围环境是obj,所以返回obj
var foo = obj.foo;
foo(); // 同理,这里是window
var foo = ()=>{ return this };
foo = foo.bind(1);
foo(); // window
foo.call(1); // window
foo.apply(1); // window
function Foo(){
  // 箭头函数
  var a = ()=>{
    console.log(this === object); // true
  }

  // 对比普通函数
  var b = function(){
    console.log(this === window); // true
  }
  
  this.foo = function(){
    a(); b();
  }
}

var object = new Foo();
object.foo();
function Foo(){}
// window
Foo.prototype.foo = ()=>{ return this }
// window
var object = new Foo();
object.foo(); // 由于定义foo的时候,周围环境是window,所以这里是window

由于只是我根据经验和资料自己总结的,所以不知道是否有疏忽或者遗漏,如果有问题的地方,欢迎提出。谢谢

 

© 著作权归作者所有

共有 人打赏支持
x
粉丝 0
博文 7
码字总数 11041
作品 0
石家庄
javascript集锦(一)

javascript集锦(一): javascript作用域: function myFun(){test = 123;}myFun(); //执行myFun后, test在myFun中没有声明var, 被视作全局变量alert(test); //123 javascript闭包:闭包可以记...

ihaolin
2014/03/30
0
0
JavaScript 专题之函数记忆

JavaScript 专题系列第十七篇,讲解函数记忆与菲波那切数列的实现 定义 函数记忆是指将上次的计算结果缓存起来,当下次调用时,如果遇到相同的参数,就直接返回缓存中的数据。 举个例子: 原...

冴羽
2017/09/06
0
0
chrome浏览器中 F12 功能的简单介绍

由于F12是前端开发人员的利器,所以我自己也在不断摸索中,查看一些博客和资料后,自己总结了一下来帮助自己理解和记忆,也希望能帮到有需要的小伙伴,嘿嘿! 首先介绍Chrome开发者工具中,调...

m0_37724356
04/10
0
0
关于JQuery的基础知识(一)

(声明:内容有摘抄也有自己经验所得,仅供记忆和备忘所用。) 1.要说起JQuery,就不得不说起javaScript,JavaScript是Netscape开发的一种脚本语言,它的出现使得网页和用户之间实现了一种实...

魔怔
2012/11/27
0
0
JavaScript专题之递归

JavaScript 专题系列第十八篇,讲解递归和尾递归 定义 程序调用自身的编程技巧称为递归(recursion)。 阶乘 以阶乘为例: 示意图(图片来自 wwww.penjee.com): 斐波那契数列 在《JavaScript专...

冴羽
2017/09/13
0
0
js中replace()方法使用注意

1.如果正则表达式中设置了修饰符g,那么源字符串中所有与模式匹配的子串都将替换成第二个参数指定的字符串;如果不带修饰符g,则只替换所有匹配的第一个子串。 2.replace()的第一个参数若是字...

依风听雨
2014/07/10
0
0
导航菜单高亮显示防刷新--JS特效

防刷新导航菜单高亮显示,这是基于javascript的cookie技术实现的,就是跳转了URL还是有高亮效果的,很不错 就像 牛淘返利网 导航菜单一样 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tra...

西西爱OS
2012/10/15
0
0
前端开发指南:ES6的生成器和迭代器

     ES6为JavaScript语言带来了许多新特性。其中两个特性,生成器和迭代器,极大地改变了我们在更复杂的前端代码中编写特定函数的方式。   虽然他们之间的关系很好,但他们实际上做的...

webstack前端栈
04/19
0
0
[Javascript]继承机制的设计思想

作者: 阮一峰 日期: 2011年6月 5日 我一直很难理解Javascript语言的继承机制。 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(...

亭子happy
2012/09/29
0
3
javascript语言精粹 读书笔记

这是我目前度过最好的js方面的书,小而精,没有一句废话全是精华。想要全面理解javascript,这本书必读。 P6 避免使用 / /注释 建议使用// P17 对象字面量是一种方便指定新对象的表示方法。属...

lilugirl
2014/01/16
0
3

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Service Mesh所应对的8项挑战

Lori Macvittie 微服务架构是把双刃剑,我们享受它带来的开发速度(development velocity),却也不得不面对服务间通讯带来的复杂性问题。 目前大多数扩展容器化微服务的架构多是基于proxy-b...

好雨云帮
15分钟前
0
0
时间复杂度

1. 维基上的定义 在计算机科学中,算法的时间复杂度是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低...

liuyan_lc
21分钟前
0
0
js中的~符

~是js里的按位取反操作符,~~就是执行两次按位取反,其实就是保持原值,但是注意虽然是原值,但是对布尔型变量执行这个操作,会转化成相应的数值型变量,也就是 ~~true === 1,~~false === 0...

JamesView
22分钟前
0
0
webpack安装

npm install --save-dev webpack-cli

Vincent-Duan
24分钟前
0
0
实时监听EditText内容变化

主要是addTextChangedListener方法的使用 aswerEdittext.addTextChangedListener(new TextWatcher() { //编辑框的内容发生改变之前的回调方法 @Override public void before...

王先森oO
27分钟前
0
0
python连接mysql数据库

安装好必要的pymysql插件 pip install pymysql 写好配置文档 DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), #......

南桥北木
29分钟前
0
0
linux下安装 Zookeeper

Zookeeper 注册中心安装 安装: wget http://www.apache.org/dist/zookeeper/zookeeper-3.3.3/zookeeper-3.3.3.tar.gztar zxvf zookeeper-3.3.3.tar.gzcd zookeeper-3.3.3cp conf/zoo_......

颖辉小居
31分钟前
0
0
C#判断文件的真实类型(非扩展名判断)

public static void CheckFileType() { string path = @"D:\word.doc"; System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read); ......

Lytf
32分钟前
0
0
java - 把日志生成到指定目录

1.按天小时生成日志文件 log4j.appender.ruiming.DatePattern='_'yyyy-MM-dd-HH 2.最大日志文件数据 log4j.appender.ruiming.MaxBackupIndex=100 3.下图画圈圈的很关键,是生成到知道目录必备...

轻量级赤影
32分钟前
0
0
少走弯路,给Java 1~5 年程序员的建议

今天LZ是打算来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈每个阶段要学习的内容甚至是一些书籍。这一部分的内容,同样适用于一些希望转行到Java的同学。 在大家看之前,LZ要先声...

Java填坑之路
33分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部