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. 如何使用JMeter开源性能测试工具来构建Web性能测试体系

    一.性能测试一些概念 性能测试:就是通过自动化的测试工具模拟多种正常峰值及异常负载条件来对系统的各项性能指标进行测试.负载测试和压力测试都属于性能测试,两者可以结合进行. 负载测试:确定在各种工作负载 ...

  2. Mybatis分页插件——PageHelper

    1.引入依赖 <!-- mybatis分页插件 --> <dependency> <groupId>com.github.pagehelper</groupI ...

  3. centos6.5安装nginx+python+uwsgi+django

    nginx+uwsgi+django环境部署及测试 默认系统自带的python2.6.6 第一步(安装setuptools) wget https://pypi.python.org/packages ...

  4. vue中,对象数组多层嵌套时,更新数据更新页面

    vue中的对象和数组的元素直接赋值修改时,是不能响应到view中去的 1.对象更新 this.a={title:'列表1’}; this.a.title='列表2’; <h1>{{a.ti ...

  5. HDU 2009 求数列的和

    题目链接:HDU 2009 Description 数列的定义如下: 数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和. Input 输入数据有多组,每组占一行,由两个整数n(n< ...

  6. JavaScript开发者应懂的33个概念

    简介 这个项目是为了帮助开发者掌握 JavaScript 概念而创立的.它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南. 本篇文章是参照 @leonardomso 创立,英文版项 ...

  7. PHP 常用设计模式 (转载)

    1.单例模式 单例模式顾名思义,就是只有一个实例.作为对象的创建模式, 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的要点有三个: 一是某个类只能有一个实例: ...

  8. javascript的数组之pop()

    pop()方法从数组中删除最后一个元素,并返回该元素的值.此方法更改数组的长度. let a = [1, 2, 3]; a.length; a.pop(); console.log(a); // [1 ...

  9. WcPro项目(WordCount优化)

    1 基本任务:代码编写+单元测试 1.1 项目GitHub地址 https://github.com/ReWr1te/WcPro 1.2 项目PSP表格 PSP2.1 PSP阶段 预估耗时(分钟) 实 ...

  10. 干货 | 教你如何监控 Java 线程池运行状态

    之前写过一篇 Java 线程池的使用介绍文章<线程池全面解析>,全面介绍了什么是线程池.线程池核心类.线程池工作流程.线程池分类.拒绝策略.及如何提交与关闭线程池等. 但在实际开发过程中, ...