this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定,this最终指向调用它的对象。

1.函数调用模式

当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的。在此种模式下,this被绑定为全局对象,在浏览器环境下就是window对象;

function fn(){
var a = "hello";
console.log(this.a); //undefined
console.log(this); //window }
fn();

2.方法调用模式

当函数被保存为一个对象的属性时,它就可称为这个对象的方法。当一个方法被调用时,this被绑定到这个对象上。如果调用表达式包含一个提取属性的动作(. 或 []),那么它被称为方法调用

var obj = {
name : "hello",
sayName : function(){
console.log(this.name); //hello
}
}
obj.sayName();

这里的this指向的对象是obj,因为调用这个sayName()函数是通过obj.sayName()执行的。

var obj = {
name : "hello",
obj2 : {
name : "world",
sayName : function(){
console.log(this.name); //world
console.log(this); //obj2
}
}
}
obj.obj2.sayName();

因为是obj.obj2调用的这个函数,所以指向obj2这个对象。

var obj = {
name : "hello",
obj2 : {
//name : "world",
sayName : function(){
console.log(this.name); //undefined
console.log(this); //obj2
}
}
}
obj.obj2.sayName();

同理,因为是obj.obj2调用的这个函数,所以指向obj2这个对象。

var name = "我是最外面的name";
var obj = {
name : "hello",
obj2 : {
name : "world",
sayName : function(){
console.log(this.name); //"我是最外面的name"
console.log(this); //window
}
}
}
var q = obj.obj2.sayName;
q();

q是全局变量,在全局环境下执行,this指向window;

3.构造函数调用模式

如果在一个函数前面加上new关键字来调用,那么就会创建一个连接到该函数的prototype成员的新对象,同时,this会被绑定到这个新对象上。这种情况下,这个函数就可以成为此对象的构造函数。

function fn(){
console.log(this);//fn
}
var a = new fn();

在构造函数,new出一个对象时,this指向这个构造函数,new关键字会改变this的指向;

function fn(){
this.name = "hello";
}
var a = new fn();
console.log(a.name); //hello

当用new关键字,返回的是一个对象,this指向的就是那个返回的对象;

如果返回的不是对象,this还是指向函数的实例,虽然null属于对象,但是返回null依然指向函数实例;

function fn(){
this.name = "hello";
return {};
}
var a = new fn();
console.log(a.name); //undefined
function fn(){
this.name = "hello";
return function(){ };
}
var a = new fn;
console.log(a.name); //undefined
function fn(){
this.name = "hello";
return function(){ };
}
var a = new fn;
console.log(a.name); //undefined
function fn(){
this.name = "hello";
return [];
}
var a = new fn;
console.log(a.name); //undefined
function fn(){
this.name = "hello";
return 1;
}
var a = new fn;
console.log(a.name); //hello
function fn(){
this.name = "hello";
return 1;
}
var a = new fn;
console.log(a.name); //hello
function fn(){
this.name = "hello";
return null;
}
var a = new fn;
console.log(a.name); //hello
function fn(){
this.name = "hello";
return undefined;
}
var a = new fn;
console.log(a.name); //hello

4.apply和call调用模式

JS中,函数也是对象,所有函数对象都有两个方法:apply和call,这两个方法可以让我们构建一个参数数组传递给调用函数,也允许我们改变this的值

var name = "window";
var obj = {
name : 'obj'
}
function sayName(){
console.log(this.name);
}
sayName();//window
sayName.apply(obj);//obj
sayName.call(obj);//obj
sayName.apply();//window
sayName.call(); //window

在全局范围内,this指向全局对象(浏览器下指window对象)

对象函数调用时,this指向当前对象

全局函数调用时,应该是指向调用全局函数的对象。

使用new关键字实例化对象时,this指向新创建的对象

当用apply和call上下文调用的时候指向传入的第一个参数;

js中的this指向问题(小计)的更多相关文章

  1. 理解js中this的指向

         学习自原文  http://www.cnblogs.com/pssp/p/5216085.html后的一点小结(原文作者总结的很棒^_^)! 关于js中this的指向,在函数定义的时候还无法 ...

  2. js中改变this指向的call、apply、bind 方法使用

    前言: 由于js 中this的指向受函数运行环境的影响,指向经常改变,使得开发变得困难和模糊,所以在封装sdk,写一些复杂函数的时候经常会用到this 指向绑定,以避免出现不必要的问题,call.ap ...

  3. js中this的指向

    在js中this的指向对于新手来说一定是个难题,但是如果你真正理解了的话,也就没什么问题啦,下面就来讲讲this吧. JS中,this的值取决于调用的模式(调用对象),而JS中共有4种调用模式: 1. ...

  4. JS中的this 指向问题

    我发现在对JS的学习中有很多朋友对this的指向问题还是有很大的误区或者说只是大致了解,但是一旦遇到复杂的情况就会因为this指向问题而引发各种bug. 对于之前学习过c或者是Java的朋友来说可能这 ...

  5. 轻松了解JS中this的指向

    JS中的this指向一直是个让人头疼的问题,想当初我学的是天昏地暗,查了好多资料,看的头都大了,跟他大战了那么多回合,终于把它搞定个七八分,其实往往都是我们复杂化了,现在就让大家轻松看懂this的指向 ...

  6. js中 this 的指向

    js中 this的指向一共存在3种地方: 1.全局的this; 2.构造函数的this; 3.call/apply; 一.全局的this: function test(){ this.d = 3;// ...

  7. 彻底理解js中this的指向,不必硬背。

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  8. 了解学习JS中this的指向

    [转] 首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问 ...

  9. 彻底理解js中this的指向

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

随机推荐

  1. 手机号流量统计---Mapreduce项目分析

    文档显示: 每行依次是 ~手机号~上行流量~下行流量 需求分析: 需要统计各自的手机号,及上行.下行.总流量 具体做法: 1.定义map输入输出类型 通常情况下map的输入的key-value就是lo ...

  2. 【Java】 剑指offer(30) 包含min函数的栈

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min ...

  3. mysql Navicat 导入导出

    1.导出数据库:     打开Navicat ,在我们要导出的数据库上右击鼠标,然后弹出的快捷菜单上点击“转储SQL 文件”,(有些版本, 会有子菜单,在再次弹出的子菜单项中选择第一个“数据跟结构”) ...

  4. cmd 命令 net start mongodb 启动不了,提示 net 不是内部命令或者外部命令

    1.要管理员的身份进入 cmd 2.右击我的电脑-->属性-->高级系统设置 3.选择高级-->环境变量 4.找到系统变量-->Path-->编辑 5.把 C:\wind ...

  5. 解密Redis的持久化和主从复制机制

    Redis持久化 Redis 提供了多种不同级别的持久化方式: RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AOF 持久化记录服务器执 ...

  6. JDBC 利用反射 配置文件

    import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.s ...

  7. mysql 5.7.21 解压版安装配置方法图文教程

    引用:https://www.jb51.net/article/140951.htm 1.首先,你要下载MySQL解压版,下载地址,图解: 2.解压安装包,根据自己的喜好选择路径,我选择的路径是C:\ ...

  8. linux更换jdk版本

    参考:https://blog.csdn.net/meilin_ya/article/details/80650945 1.将两个版本的jdk放到linux环境2.设置选择使用alternatives ...

  9. Exp2 后门原理与实践 20164320 王浩

    一.实践基本内容 1.实践目标 (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, 任务计划启动 (3)使用MSF meterpreter(或其他 ...

  10. Elasticsearch学习笔记(十)批量查询mget、批量增删改bulk

    一.批量查询  mget             GET /_mget {   "docs":[       {         "_index":" ...