搜索
首页web前端js教程深入浅出JavaScript之this的详解

深入浅出JavaScript之this的详解

Mar 03, 2017 pm 03:34 PM
javascript

JavaScript中的this比较灵活,根据在不同环境下,或者同一个函数在不同方式调用下,this都有可能是不同的。但是有一个总的原则,那就是this指的是,调用函数的那个对象。

系列目录

  • 深入浅出JavaScript之闭包(Closure)

  • 深入浅出JavaScript之this

  • 深入浅出JavaScript之原型链和继承

下面是我的学习笔记,把它罗列成8种情况。

全局的this(浏览器)

全局作用域的this一般指向全局对象,在浏览器中这对象就是window,在node中这对象就是global。

console.log(this.document === document); // true (document === window.document)
console.log(this === window); // true 
this.a = 37;  //相当于创建了一个全局变量a
console.log(window.a); // 37

一般函数的this(浏览器)

一般的函数声明或者函数表达式,直接调用函数的话,this依然指向全局对象,在浏览器中这对象就是window,在node中这对象就是global。

function f1(){  
  return this;  
} 
f1() === window; // true, global object

再举一个例子,看完就非常透彻了

function test(){
 this.x = 1;
  alert(this.x);
}
test(); // 1

为了证明this就是全局对象,对代码做一些改变:

var x = 1;
function test(){
 alert(this.x);
}
test(); // 1

运行结果还是1。再变一下:

var x = 1;
function test(){
 this.x = 0;
}
test();
alert(x); //0

但是在严格模式下,一般函数调用的时候this指向undefined,这也是node为什么要用严格模式的一个原因。

function f2(){  
  "use strict"; // see strict mode  
  return this; 
} 
f2() === undefined; // true

作为对象方法的函数的this

this作为对象方法来使用是比较常见的。

下面这个例子,我们创建了一个对象字面量o,o里面有个属性f,它的值是一个函数对象,把函数作为对象属性的值这种方式我们常常叫作对象的方法。作为对象的方法调用的时候,这时候this指向对象o

var o = {  
   prop: 37,  
   f: function() {    
     return this.prop;    
  } 
};  

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

我们不一定要定义成函数字面量这样子的对象,像下面这种情况,我们只定义了一个对象o,如果直接调用independent()函数的话,this会指向window,但是我们通过赋值的方式,临时创建一个属性f,并指向函数对象的时候,我们仍然拿到了37。

var o = {prop: 37}; 

function independent() {  
   return this.prop; 
} 

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

所以并不是看函数是怎么创建的,而是只要将函数作为对象的方法去调用,this就会指向这个对象。

对象原型链上的this

下面这个例子中:我们先创建了一个对象o,里面有一个属性f,函数作为对象属性的值,我们通过Object.create(o)创建了一个对象p,p是一个空对象,它的原型会指向o,然后使用p.a = 1; p.b = 4创建对象p上的属性,那么我们调用原型上的方法时,this.a,this.b依然能取到对象p上的a和b。这里需要注意的是p的原型才是o,我们调用p.f(),调用的是原型链o上的属性f,原型链上的this可以拿到当前的对象p。

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

get/set方法与this

get/set方法中的this一般会指向get/set方法所在对象里面

function modulus(){   
   return Math.sqrt(this.re * this.re + this.im * this.im); 
} 
var o = { 
  re: 1, 
  im: -1, 
  get phase(){      
     return Math.atan2(this.im, this.re);    
  } 
}; 
Object.defineProperty(o, 'modulus', {       //临时动态给o对象创建modules属性
  get: modulus, enumerable:true, configurable:true}); 

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

构造函数中的this

用new把MyClass作为构造函数调用的话,this会指向空的对象,并且这个对象的原型会指向MyClass.prototype(可以看这篇文章对原型链的总结),但是调用的时候做了this.a = 37的赋值,所以最后this会作为返回值(没写return语句,或者return的是基本类型的话,会将this作为返回值),第二个例子return语句返回了对象,那么就会将a = 38作为返回值

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

call/apply方法与this

除了不同的调用方式外,函数对象有些方法能修改函数执行的this,比如call/apply。

call和apply基本上没差别,只不过call传参的方式是扁平的,而apply是把一个数组传进去。如下面这个例子

什么时候用call和apply呢?比如我们想调用Object.prototype.toString,但是我们想指定某个this的时候,那我们就可以就用Object.prototype.toString.call(this)这样子的方式来调用些无法直接调用的方法。如下面这个例子:

function add(c, d){  
   return this.a + this.b + c + d;  
} 
var o = {a:1, b:3}; 
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16     //第一个参数接收的是你想作为this的对象
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 

function bar() {  
   console.log(Object.prototype.toString.call(this)); 
} 
bar.call(7); // "[object Number]"

bind方法与this

bind方法是es5开始提供的,所以ie9+才支持

function f(){  
   return this.a;  
} 

var g = f.bind({a : "test"});   //想把某个对象作为this的时候,就把它传进去,得到一个新对象g
console.log(g()); // test       //重复调用的时候,this已经指向bind参数。这对于我们绑定一次需要重复调用依然实现绑定的话,会比apply和call更加高效(看下面这个例子)

var o = {a : 37, f : f, g : g};  
console.log(o.f(), o.g()); // 37, test  
 //o.f()通过对象的属性调用,this指向对象o;比较特殊的是即使我们把新绑定的方法作为对象的属性调用,o.g()依然会按之前的绑定去走,所以答案是test不是g

总结

做项目的时候才发现这些基础概念有多么的重要,如果不把它们逐个落实了,真的是一不小心就会掉进坑里。后续我还会对原型链,作用域,继承,链式调用,正则等知识进行总结,欢迎关注

 以上就是深入浅出JavaScript之this的详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的演变:当前的趋势和未来前景JavaScript的演变:当前的趋势和未来前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

神秘的JavaScript:它的作用以及为什么重要神秘的JavaScript:它的作用以及为什么重要Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python还是JavaScript更好?Python还是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安装JavaScript?如何安装JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安装,因为它已内置于现代浏览器中。你只需文本编辑器和浏览器即可开始使用。1)在浏览器环境中,通过标签嵌入HTML文件中运行。2)在Node.js环境中,下载并安装Node.js后,通过命令行运行JavaScript文件。

在Quartz中如何在任务开始前发送通知?在Quartz中如何在任务开始前发送通知?Apr 04, 2025 pm 09:24 PM

如何在Quartz中提前发送任务通知在使用Quartz定时器进行任务调度时,任务的执行时间是由cron表达式设定的。现�...

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境