this参数的指向不仅是由定义函数的方式和位置决定的,同时还严重受到函数调用方式的影响。我们接下来讨论不同调用方式对this的影响。

1.作为一个函数调用
在非严格模式下,this是全局上下文(window对象)
在严格模式下,this是undefined

2.作为方法调用
当函数作为某个对象的方法被调用时,该对象会成为函数的上下文,并且在函数内部可以通过参数访问到

3.作为构造函数调用
新的空对象被设置为该函数的上下文(this)

4.apply/call
显示指定任何对象作为函数的上下文

5.箭头函数中this
箭头函数中的this是在定义函数时绑定的,不是在执行过程中绑定的,简单的说,函数在定义时,this就继承了定义函数时的对象。

1.作为函数直接被调用

function ninja(){return this;
}function samurai(){"use strict";return this;;
}ninja() === window;   //true
samurai() === undefined;   //true

2.作为方法被调用

function whatsMyContext(){return this;
}//在对象中定义方法
var ninja1 = {getThis:whatsMyContext
}
var ninja2 = {get2This:whatsMyContext
}ninja1.getThis() ===ninja1;   //true
ninja2.get2This() === ninja2;   //true

如何定义一个对象:

var person = {firstName: "Bill",lastName : "Gates",id       : 678,fullName : function() {return this.firstName + " " + this.lastName;}
};

3.作为构造函数调用

function Ninja(){this.skulk = function(){return this;}
}var ninja11 = new Ninja()ninja11.skulk() == ninja11 ;  //truevar ninja22 = new Ninja()ninja22.skulk() == ninja22;   //true

再看一个例子:

function CO(){this.p = “I’m in constructed object”;this.alertP = function(){alert(this.p);}
}
var o2 = newCO();

那么,在使用new操作符来调用一个构造函数的时候,发生了什么呢?其实很简单,就发生了四件事:

1 var obj  ={};
2 obj.__proto__ = CO.prototype;
3 CO.call(obj);
4 return obj;

第一行,创建一个空对象obj。
第二行,将这个空对象的__proto__成员指向了构造函数对象的prototype成员对象,这是最关键的一步,具体细节将在下文描述。
第三行,将构造函数的作用域赋给新对象,因此CA函数中的this指向新对象obj,然后再调用CO函数。于是我们就给obj对象赋值了一个成员变量p,这个成员变量的值是” I’min constructed object”。
第四行,返回新对象obj。当构造函数里包含返回语句时情况比较特殊,这种情况会在下文中说到。

还有构造函数返回值:
1.如果构造函数返回一个对象,则该对象将作为整个表达式的值返回,而传入构造函数的this将被丢弃。
2.但是,如果构造函数返回的是非对象类型,则忽略返回值,返回新创建的对象。

4.call和apply

call和apply的作用一样,只是接受参数的方式不一样,call接受的是多个单个参数,apply接受的是参数数组。

call和apply的作用简单地可以说成,当一个对象实例缺少一个函数/方法时,可以调用其他对象的现成函数/方法,其方式是通过替换其中的this为这个对象实例,改变函数运行时的上下文。

例如:

function Dog(){this.sound="汪汪汪";
}
Dog.prototype.bark=function(){alert(this.sound);
}

现在我有另外一个cat对象:

var cat={sound:'喵喵喵'}

我也想让这个cat对象可以调用bark方法,这时候就不用重新为它定义bark方法了,可以用call/apply调用Dog类的bark方法:

Dog.prototype.bark.call(cat);

或者:

dog.bark.call(cat);

加点东西,变成一个带参数的栗子:

function Dog(){this.sound="汪汪汪";
}
Dog.prototype.bark=function(words){alert(this.sound+"  "+words);
}
var dog=new Dog();
dog.bark("有小偷");//alert:汪汪汪   有小偷
Dog.prototype.bark.call(cat,"饿了");//alert:喵喵喵   饿了

apply/call中this:

function juggle(){var result = 0;for(var n = 0;n<arguments.length;n++){result += arguments[n];}this.result = result;   //将结果result变量放在任意一个作为该函数上下文的对象上
}var ninja1 = {};
var ninja2 = {};juggle.apply(ninja1,[1,2,3,4]);
juggle.call(ninja2,5,6,7,8);ninja1.result === 10;
ninja2.result === 26;

5.箭头函数中this

箭头函数中的this:

1.箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象, 定义它的时候,可能环境是window; 箭头函数可以方便地让我们在 setTimeout ,setInterval中方便的使用this

2.箭头函数中,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。

例如这段函数中,this指向的是Person对象,可以看到控制台打印结果,此时的箭头函数所处的宿主对象是Person,所以this指向的是person:


参考文章:
《JavaScript忍者秘籍》
https://www.cnblogs.com/SheilaSun/p/4398881.html
https://www.cnblogs.com/wangyingblog/p/5583825.html
http://www.w3school.com.cn/js/js_objects.asp
https://blog.csdn.net/xu4321083/article/details/79753800

JavaScript中this参数相关推荐

  1. javascript中函数参数是evt详解

    一般情况下,在js中函数可能没有参数,也有特殊情况,举个例子: function toggleColor(evt){ if (vet){ var thisSquare = evt.target;} e ...

  2. javascript中函数参数以及函数中局部变量作用域一点点理解

    2019独角兽企业重金招聘Python工程师标准>>> 函数中局部变量如果与外部变量重名,则用的是函数内部局部变量,用完就会被释放.我的理解函数是一个function定义的代码段,以 ...

  3. 如何使用ES6中的参数

    ECMAScript 6(或者叫 ECMAScript 2015)是 ECMAScript 的最新标准,极大的提高了 JavaScript 中处理参数的能力.现在我们可以使用 rest 参数(rest ...

  4. js中函数参数arguments、callee、caller,值传递、重载

    全栈工程师开发手册 (作者:栾鹏) js系列教程4-函数.函数参数教程全解 函数参数 arguments javascript中的函数定义并未指定函数形参的类型,函数调用也未对传入的实参值做任何类型检 ...

  5. JavaScript中的参数传递

    参数传递 在JavaScript中,参数都是按值传递的.也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样.基本类型值的传递如同基本类型的变量复制一样,而引用类型值的 ...

  6. JavaScript中实现函数重载和参数默认值

    2019独角兽企业重金招聘Python工程师标准>>> 参数默认值是指在调用函数时,若省略了某个实参,函数会自动为该参数分配一个默认值,使得函数调用的方便性和灵活性大大提高. 举个例 ...

  7. JavaScript中函数作为另一个函数的参数的时候它存在于哪个作用域

    一直对函数作为参数被传递进另外一个函数理解的不是很清除.先看下这段代码吧: function test(fn){var bar = 1;fn(); } var bar = 99; test(funct ...

  8. xslt中的Javascript取得xml中的参数

    xslt中的Javascript取得xml中的参数 使用xslt解析xml的时候,需要把xml中的参数传到javascript中, 可以用xslt作为中转, xsl: <input type=& ...

  9. 有没有更好的方法在JavaScript中执行可选的函数参数? [重复]

    本文翻译自:Is there a better way to do optional function parameters in JavaScript? [duplicate] This quest ...

最新文章

  1. RxJava repeat,repeatWhen,repeatUntil 的区别
  2. html Qestionnaire表单
  3. 从IEEE754标准谈C语言浮点数据类型
  4. 《Verilog HDL那些事儿》PDF 3.0版本发布
  5. linux服务 Systemd 简介
  6. weex 打包apk
  7. Windows Phone 7 - 页面间传值 来源-http://blog.csdn.net/dncts/article/details/6160067
  8. react native android 打包
  9. Fabric 报错:java.lang.IllegalArgumentException: UserContext user‘s name missing.
  10. 《SDN核心技术剖析和实战指南》
  11. 计算机网络实验三思考题,计算机网络实验思考题答案
  12. 非计算机专业考研软件工程,#考研报名#计算机类、软件工程类考生报名前必看...
  13. VS2010 移除源文件又增加源文件,无法编译问题
  14. sipdroid软件直接使用andriod打网络电话
  15. UE4/5 EasyFog插件使用
  16. Dalvik 指令学习
  17. 冬季旅游,北海的风景、历史与美食,气候温暖如春
  18. 压缩png命令cmd_使用pngquant工具对PNG格式图片进行压缩
  19. 计算多项式的值——基于C语言程序
  20. 湖北计算机自考学校都有哪些,湖北省自考本科有哪些学校?

热门文章

  1. bat批量修改文件前缀名字
  2. 路由器中继(repeater)模式 和 AP+WDS模式区别?
  3. AE学习笔记——第五章:效果预设和渲染导出
  4. 悦灵犀-全新的智能AI工具
  5. 掘金 AMA:听 Vue.js 作者--尤雨溪谈 Vue.js 独立开发 设计那些事
  6. 平凡的世界---读后感1
  7. Windows数字签名
  8. WonderShaper限制Linux网络带宽
  9. 前端小练习JS实现网页开灯和关灯
  10. scanf输入%s,%c遇到空白字符的一些思考