资讯专栏INFORMATION COLUMN

javascript基础之this

Zoom / 1507人阅读

摘要:出现箭头函数的时候,指向为定义时的上下文对象而非指向时,并且不能被改变首先我们先看一个例子由上面的例子我们可以看出来此时指针在用改变了之后指向的依然是全局对象非严格浏览器环境中是而非。

javascript基础之this指针

越往后面学越发现基础的重要性,所以打算重新过一遍基础,之后出几个vue和react的实战教程。
ok,严归正传。

首先什么是this

this是执行上下文创建时确定的一个在执行过程中不可改变的变量。
总之记住一句话this的指向由以执行时候的上下文决定的而非定义时的上下文

看过一本书叫《JavaScript语言精粹》,里面把this的出现场景为4类,当然那是在es6出来之前,不过也可以表示基本的用法了,在es6出来之后出现箭头函数,所以一共是5种:

有对象的就指向该对象

没有对象的就指向全局对象,在非严格模式下指向window

有new构造函数的就指向new完之后的新对象

通过apply或者bind或者call改变this指向的对象

出现箭头函数的时候,this指向为定义时的上下文对象而非指向时,并且不能被call改变

函数有对象的时候就指向该对象
    let name = "bob";
    let obj = {
      name,
      getName(){
         console.log(this.name);  
      }
    };

console.log(obj.getName()); //=>bob

因为getName()属于对象obj,并且由obj进行调用,所以毫无疑问是指向obj这个对象,ok,我们再看一个例子

 var name = "jay";
 var obj = {
      name:"bob"
      getName(){
         console.log(this.name);  
      }
 };
 
 let t = obj.getName;
 console.log(t()); // => jay

如上,为什么这次t函数打印出来的值是jay?excuse me?
其实要理解也好简单,当执行t()的时候(在非严格模式下)其实t其实是属于全局对象(在浏览器环境)也就是window,而var name = "jay"为全局变量,所以输出jay也不奇怪了。

没有对象的就指向全局对象,在非严格模式下指向window

var name = "bob";
var obj = {
  name,
  getName:function(){
     function otherName(){
        return this.name;
     }
     console.log(otherName());
  }
};

obj.getName(); // =>bob

otherName随便是在obj的getName中定义的,但是它还是一个普通函数,他的this其实和

    var name = "bob";
    function otherName(){
       return this.name;
    }
    console.log(otherName()); // =>bob

执行效果一样的,他的this的指向其实是undefined,在非严格模式下,当this指向undefined的时候其实会自动转化成window对象(在浏览器中)。
ok,让我们再看一种情况

var name = "bob";
function otherName(){
   "use strict"
   return this.name;
}
console.log(otherName()); // Uncaught TypeError: Cannot read property "name" of undefined

这个时候会抛出一个错误,因为在严格模式下当this指针指向undefined的时候不会自动转化成window对象。

有new构造函数的就指向new完之后的新对象

首先什么是构造函数,其实可以用一句话去概括:
构造函数其实就是用来新建对象的函数

JavaScript本身就为我们定义了几个常用的构造函数,你肯定认识 比如Function, Object, Array, Date等等,只不过我们平常object,function都不是用new Function,new Object,而是用他的语法糖比如
var obj = {} 其实等同于 var obj = new Object();

function Human(name,age,sex){
   this.name = name;
   this.age = age;
   this.sex = sex;
   this.common = function(){
       console.log("名字为"+this.name);
   }
}

var h = new Human("bob",25,"sex");
h.common(); // => 名字为bob

有new构造函数的就指向new完之后的新对象,此时的this指向的是他new出现来的对象h。

通过apply或者bind或者call改变this指向的对象

由于函数具有函数作用域,所以有时候我们需要引用外层作用域的时候通常用的方法是call,apply,和bind这三兄弟

首先我们来看看call,老样子先看代码

var a = {
    user:"bob",
    fn:function(){
        console.log(this.user); 
    }
}
var b = {
    user:"jay"
}

a.fn.call(b); // => jay

如果不调用call,我们直接使用a.fn的话将会输出bob,因为fn这个方法是a这个对象定义出来的,所以this指向是a这个对象,但是当我们使用了call之后this指针指向的对象就变成b了,于是乎也不难理解为什么输出的user是jay了。
简介一下call的用法:
fn.call(obj,argument-1,argument-1,...)
是以obj这个对象去代替fn的this指针也就时fn的this指针指向obj,后面的argument-1,argument-1是形参
apply和call的用法基本相同,不同点是apply调用传形参的时候穿的是数组或者是类数组,如下:
fn.apply(obj,[argument-1,argument-1,...])

至于bind和call或者apply的区别,我也举一个例子

var a = {
    user:"bob",
    fn:function(){
        console.log(this.user); 
    }
}
var b = {
    user:"jay"
}

var c = a.fn.bind(b); 
c(); // => jay

从上面这个例子可以得出一个结论:
其实call和apply方法,都是对函数的直接调用,但是bind()方法需要加上()来执行。

出现箭头函数的时候,this指向为定义时的上下文对象而非指向时,并且不能被call改变

首先我们先看一个例子:

var obj = {name:"bob"};

var name = "jay";

var sayName = () => console.log(this.name);

sayName(); // => jay
sayName.call(obj); //jay

由上面的例子我们可以看出来此时this指针在用call改变了之后指向的依然是全局对象(非严格浏览器环境中是window)而非obj。

ok,至此this指针的用法总结完毕。

后记

以上this的用法都为个人总结,如有不当之处还请指出

转载请注明出处.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92684.html

相关文章

  • javascript 基础 call, apply, bind

    摘要:系统,扎实的语言基础是一个优秀的前端工程师必须具备的。第一个参数为调用函数时的指向,随后的参数则作为函数的参数并调用,也就是。和的区别只有一个,就是它只有两个参数,而且第二个参数为调用函数时的参数构成的数组。 系统,扎实的 javascript 语言基础是一个优秀的前端工程师必须具备的。在看了一些关于 call,apply,bind 的文章后,我还是打算写下这篇总结,原因其实有好几个。...

    xeblog 评论0 收藏0
  • Javascript基础-this

    摘要:应该算是前期比较容易混淆的一个关键字了,在这里,我就打算按照我的理解来说一下首先呢,的值是跟运行时被调用的位置相关的,而不是词法作用域。来一个例子在浏览器中执行,会发现,如果作为一个函数单独调用,那么指向的就是全局对象。 this应该算是前期比较容易混淆的一个关键字了,在这里,我就打算按照我的理解来说一下 首先呢,this的值是跟运行时被调用的位置相关的,而不是词法作用域。 也就是说,...

    lcodecorex 评论0 收藏0
  • 基础知识 - 收藏集 - 掘金

    摘要:本文是面向前端小白的,大手子可以跳过,写的不好之处多多分钟搞定常用基础知识前端掘金基础智商划重点在实际开发中,已经非常普及了。 JavaScript字符串所有API全解密 - 掘金关于 我的博客:louis blog SF专栏:路易斯前端深度课 原文链接:JavaScript字符串所有API全解密 本文近 6k 字,读完需 10 分钟。 字符串作为基本的信息交流的桥梁,几乎被所有的编程...

    wdzgege 评论0 收藏0
  • JS基础常用小技巧和知识总结(一)

    摘要:如果有一方是布尔值,则转换为,转换为,再进行判断。等同运算符类型不同返回类型相同如果同为数字字符串则比较值如果同为布尔值,相同则为不同为如果两个操作数同为引用类型,且引用的为同一个对象函数,数组,则相同。 本文主要记录平时开发遇到的知识点和小技巧 相等判断(==) 类型相同: 判断其值是否相同 类型不同: 1. 如果数字和字符串比较, 则字符串会被隐式转换为数字,在做判断。 2....

    dadong 评论0 收藏0
  • JavaScript基础创建对象、原型、原型对象、原型链

    摘要:在最开始的时候,原型对象的设计主要是为了获取对象的构造函数。同理数组通过调用函数通过调用原型链中描述了原型链的概念,并将原型链作为实现继承的主要方法。 对象的创建 在JavaScript中创建一个对象有三种方式。可以通过对象直接量、关键字new和Object.create()函数来创建对象。 1. 对象直接量 创建对象最直接的方式就是在JavaScript代码中使用对象直接量。在ES5...

    wangbjun 评论0 收藏0

发表评论

0条评论

Zoom

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<