参考视频:http://www.imooc.com/video/6430

JavaScript中的this比较灵活,也是让很多初学者摸不到头脑,那么根据在不同的环境下,在同一个函数,不同的调用方式下,那么这个this也有可能是不同的。

我们先来看,全局作用于下的this。

全局的this(浏览器)

console.log(this.document===documet);//true

console.log(this===window);//true

this.a=37;

console.log(window.a);//37

全局作用域下的this一般指的是全局对象,在浏览器里面一般指的是windows。比如上面的this.document就是window.document. 这里的this就相当于window,所以this=window.

so,this.a=window.a。

一般函数的this(浏览器)

function f1(){

return this;

}

f1()===window;//true,global object

比如我们用这样的一般函数声明和一般表达式,然后我们直接去调用这样的函数的话,那么这里面的this仍然指向全局变量,那么在浏览器里面就是window,那么在node.js里面呢,就是global对象。

function f2(){

"use strict"//ee strict mode

return this;

}

f2()===undefined;//true

我们需要注意的一点就是严格模式下呢,一般函数调用的this会指向这个undefined.

我们更常见的作为对象方法的函数的this:

var o={

prop:37,

f:function(){

return this.prop;

}

};

console.log(o.f());//logs 37

是将this作为对象方法去用的时候,我们知道,函数呢,如果作为一个对象的属性,比如我们这创建的自变量o,那么o里面有个属性f,它的值是一个函数对象,那对于这样一个把函数作为一个对象属性值的方式,我们常常叫做一个对象的方法。那么多为对象方法去调用的时候,比如这里的用o.f()去调用,这种情况的this一般会指向这样一个对象o,这里我们可以看到o.f()调用以后会返回37,因为this指向了o,所以相当于o.prop,所以最终的结果是37。

 

var o={prop:37};

function independent(){

return this.prop;

}

o.f=independent;

console.log(o.f());//logs 37

那么这里面,我们不止是一定要定义成函数自变量的对象,比如这里面我们定义了一个对象o,只有一个属性prop:37;那么这里面我们有个独立的independent函数,那么这里面的函数,我们仍然return this.prop,如果我直接去调用independent的话,则this依旧指向window。这里临时创建一个o的属性f(即是o.f)并且指向independent,所以这样再调用console.log(o.f(),则又跟上一条函数同理!

这里面是不是看函数是怎么创建的,而是只要将这个函数作为对象的方法,就像这个o.f()去调用的话,那么,这个this,就会指向这个o.prop。

对象原型链上的this:

var o={f:function(){return this.a+this.b;}};

var p=Object.create(o);

p.a=1;

p.b=4;

console.log(p.f());//5

创建一个对象o里面有属性f,并且函数作为属性的值,我们通过Object.create创建了一个对象p,而对象P是一个空对象,并且它的原型指向了o,那么p.a=1;p.b=4;这样创建了对象的属性,那么我去调用它原型上方法的时候,this.a和this.b依旧能取到p.a和p.b的值。这里面p的原型才是o,也就是说,调用p.f()的时候调用的时候这个对象原型对象上的o上面的属性f。

get/set方法与this:

function  modulus(){

return Math.aqrt(thisre*this.re+this*this.im);

}

var 0={

re:1,

im:-1,

get phase(){

return Math.atan2(this.im,this.re);

}

};

Object.defineProperty(o,'modules',{

get:modulus,enumerable,configurable:ture});

console.log(o.phase,o.modulus);//logs-0.78   14.4142

get/set方法也是类似的,这里用的是一个modules。然后这里我们去计算this.re和this.im,这里我们用一个对象o,并且o里面有一个get方法,给这样的属性phase,再用

Object.defineProperty(object, propertyname, descriptor)去定义o的属性,这里我们同样可以调用o.phase和o.modulus去拿到o的属性,那么modules里面的this依旧会指向o的re和im,我们也要知道get/set方法里面的this也是会指向它所在的那个对象里面,那么我们临时动态区别一下O这个对象与创建.modulus的属性也是类似的,那么这一点上,和一般的对象属性作为函数对象也是类似的! 

构造器中的this:function MyClass(){this.a=37;}var o= new MyClass();console.log(o.a);//37

function C2(){this.a=37;return{a:38};}o=new C2();console.log(o.a);//38如果我们正常去调用MyClass这个函数的话,this就是指向全局变量window,但是如果用new MyClass来把它作为构造器去调用的话,那么MyClass的this会指向空的对象,并且这个对象会指向原型MyClass.prototype.这里使用了new以后,那么这个this会指向一个原型为MyClass.prototype属性的这样一个空对象,那么这样由于我们的this.a赋值了37,而且MyClass的返回值默认是this,所以这对象o就会输出37。那么类似的我们定义了一个函数C2,然后this.a=37,但是return里面的返回的语句是a:38,所以a就不再是37了,而是38。当我们使用new来创建这样一个构造器来这样去调用的时候,那么这样的this会指向一个原型为MyClass.prototype这样一个空对象,最后还是要看返回值,如果你没有写return语句,则默认返回this,如果有return语句返回了一个对象的话,所以会将return的对象作为返回值,所以o.a就是38.

call/apply方法与this:function add(c,d){return this.a+this.b+c+d;}var 0= {a:1,b:3};add.call(,o,5,7);//1+3+5+7=16add.apply(o,[10,20]);//1+3+10+20=34function bar(){console.log(Object,prototype.toString.call(this));}bar.call(7);//"[object Number]"除了不同的调用方式,每一个函数对象也会有方法,可以去修改函数执行时的里面的this,比较常见的就是call/apply。比如我这里面的函数声明add,我们用this.a和this.b,和参数c和d把这四个数相加起来。我们是怎么做的呢,我们是定义一个变量o,里面有两个属性a:1,b:3,然后通过这个对象的的call方法,把第一个参数接受那个关于this的对象,后面是5和7(也就是我们想添加的参数),也就是c=5,d=7,最终的结果是就1+3+5+7=16。其实call和apply其实没有什么差别,只是call和apply传参的方式不同,call是直接把参数变量传输进去的,而apply是将参数作为数组的形式传输进去,所以apply的结果是也是1+3+10+20=34,。现在我们来区分一下情况下用到这个call和apply,比如说,我们想调用Object,prototype.toString,但是我们想指定某一个this的时候,来调用一些我们无法直接调用的一些方法,那么我们这里去调用bar。call(7),这样就能拿到内部的这样一个标签间接的字符串。

bind方法与this:function f(){return this.a;}

var g=f.bind({a:"test"});console.log(g());//test

var o={a:37,f:f,g:g};console.log(o.f(),o.g());//37 test除了call/apply还有bind方法,bind方法只能兼容IE9以上版本,我们定义了一个函数对象f(),然后我们通过bind的方法,定义了一个a的对象,并把参数值“test”传进去,这样我们就得到了一个g对象,我们到下面调用输出的时候,发现已经调用了test这个参数,这样是采用了绑定一次,并重复去调用,仍然实现这种绑定的话,这样会比我们使用call/apply高效一点。我们下面又定义了一个函数o,然后把a赋值为37,然后f赋值了f(),g赋值了g(),然后我们输出的o.f(),o.g()是37,test.这里比较特殊的就是我们使用了bind方法,即使我们使用了bind方法,并把新绑定方法作为对象的属性去调用,那么这里依旧会按照之前的绑定去走,所以也就返回这个test

转载于:https://www.cnblogs.com/Yirannnnnn/p/4343378.html

javascript 之 this 用法相关推荐

  1. Javascript的this用法

    Javascript的this用法 转自:http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html th ...

  2. JavaScript中foreach()用法及使用的坑

    JavaScript中foreach()用法及使用的坑 JavaScript中foreach是用于遍历数组的方法,将遍历到的元素传递给回调函数,遍历的数组不能是空的要有值. foreach 语法: [ ...

  3. javascript typeof的用法

    javascript typeof的用法 2007/07/31 18:49 经常会在js里用到数组,比如 多个名字相同的input, 若是动态生成的, 提交时就需要判断其是否是数组. if(docum ...

  4. Javascript:this用法

    #Javascript:this用法整理 pingan 于 星期三, 18/12/2013 - 22:32 提交 常用Javascript的人都知道,[this这个关键字在一个函式内究竟指向谁]的这个 ...

  5. php伪数组转换为数组,JavaScript伪数组用法实例

    在Javascript中什么是伪数组?伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的行为,但仍可以对真正数组遍历方法来遍历它们.本文实例讲述了JavaScript伪数组用法, ...

  6. javascript中in用法介绍

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. js replace不改变原str_总结javascript replace高级用法

    详解javascript replace高级用法 在前端与后台交互的时候我们通常都需要将后台传递的数据绑定到html中,这个绑定数据的方式我们通常是使用jQuery或者使用原生的innerHTML进行 ...

  8. html mailto 乱码,JavaScript mailto的用法解析

    本节内容: JavaScript mailto的用法 在网页中经常见过这样的提示: 若您忘记了密码,可发邮件至:123@123.com 对于MAILTO 中文标题乱码的问题 是由于outlook的编码 ...

  9. JavaScript计时器的用法setTimeout()和setInterval()

    Javascript计时器的用法 当我们学习前端的时候定时器是一个重要的知识点,几乎现在的我们打开一个网页中的页面都会看见定时器的身影,京东淘宝的定时秒,轮播图.规定时间的界面跳转- 在JavaScr ...

  10. javascript:void(0);用法及常见问题解析

    void 操作符用法格式: javascript:void (expression) 下面的代码创建了一个超级链接,当用户以后不会发生任何事.当用户链接时,void(0) 计算为 0,但 Javasc ...

最新文章

  1. Python --深入浅出Apriori关联分析算法(二) Apriori关联规则实战
  2. DX使用随记--ImageComboBoxEdit
  3. 自动生成get,set方法
  4. 编程的智慧 意外在内网找到的资源
  5. SAP CDS view里将Date和time连接成timestamp的函数
  6. Java EE 8 MVC:使用路径参数
  7. java ftp connect_java操作Ftp文件的一些方式(一)
  8. 微积分知识总览(0)
  9. PIX 7.2 PAT
  10. 【优化求解】基于matlab遗传算法求解车辆发车间隔优化问题【含Matlab源码 132期】
  11. 网页上的html表格导出excel表格,网页表格导出至Excel
  12. cad打开a3样板图形_CAD中怎样设置A3图纸模板
  13. LDA模型理解(一)
  14. 【柒】企业分析利器——强大企业模型
  15. sql数据库考试试题
  16. 做人必须留的几张底牌
  17. 关于GIt的学习,gitee
  18. uniapp苹果无法上架_uni-app 打包ios上架app store流程
  19. 我母亲在一家计算机公司工作,关于母亲的作文700字5篇
  20. 不让苹果开发者账号折磨我

热门文章

  1. 雨量、阳光、防雾传感器
  2. Google发布了能理解人类语言的云服务
  3. 关于Beta分布、二项分布与Dirichlet分布、多项分布的关系
  4. linux常用命令之lsof 、netstat、ipcs、ldd
  5. python 回溯法 子集树模板 系列 —— 5、取物搭配问题
  6. shell中$XX相关
  7. RabbitMQ 安装和简单测试
  8. 微信第三方开发者该何去何从?
  9. linux服务器dns配置丢失处理
  10. JSP学习02-config内置对象