this魔术背后的秘密
2017-08-12 23:10
211 查看
作为一个前端学习者,在学习之路上总会遇到一些难题,突发奇想,便随手记录一下。
普通函数调用
作为对象方法来调用
作为构造函数来调用
使用apply/call方法来调用
this是在运行时进行绑定的,它的上下文取决于函数调用时的各种条件,this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
简单来说:this的最终指向的是那个调用它的对象(谁调用这个函数或者方法,this就指向谁)
在这段代码中foo是直接使用了不带任何修饰的函数引用进行调用的,所以使用了默认绑定,即作为全局对象window的方法来进行调用的,可以看作window.foo();所以这里是window对象调用了foo这个方法,也就是说foo函数当中的this是指向window,同时window还具有了一个属性x,值为1。
这里为了证明this是全局变量,进行了一下小改变。一开始定义的全局变量x作为window的属性,在调用时,this肯定是指向全局对象window。
但是在严格模式下,则不能将全局对象用于默认绑定,因此this会绑定到undefined。
虽然this的绑定规则完全取决于调用位置,但是只有foo()运行在非严格模式下时,默认绑定才能绑定到全局对象。
这里的this指向的是对象obj,因为你调用这个foo是通过obj.foo()执行的,那this就指向就是对象obj。再次强调,this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式,谁调用的就指向谁,这个很重要。
这里可以实现输出1是因为new关键字可以改变this的指向,将this指向了obj对象。在传统的面向类语言中的new与js的new机制有着很多不同。在js中,构造函数只是使用new操作符时被调用的函数,不属于某个类,也不会实例化一个类,只是被new操作符调用的普通函数。new是可以影响函数调用时this绑定行为的方法,称之为new绑定。
通过foo.call(),调用foo时将this绑定在了obj上。从this绑定的角度上,call()和apply()是一样的。如果你把null或者undefined作为this绑定的对象传入call,apply或者bind,在调用时会被忽略,执行的是默认绑定规则。
this虽然只是js里的一小部分,对于我们学习者而言还是很重要的。this还有很多奥秘等着我们去发掘,我也只是知晓了其冰山一角,希望能分享一点自己的想法给一起学习路上的同学们,与君共勉。
Javascript的this用法
关于this
this作为javascript常用的关键字之一,被人们称为最复杂的机制之一,他就像一个魔术师,变幻着令人着迷的戏法,来混淆你的视听。而作为观众的我们在欣赏完这眼花缭乱的魔术之后,总想了解一下背后的秘密。理解this的指向
在js中,函数的几种调用方式有:普通函数调用
作为对象方法来调用
作为构造函数来调用
使用apply/call方法来调用
this是在运行时进行绑定的,它的上下文取决于函数调用时的各种条件,this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
简单来说:this的最终指向的是那个调用它的对象(谁调用这个函数或者方法,this就指向谁)
普通函数调用
function foo(){ this.x = 1; console.log(this.x); console.log(this); } foo(); // 1 window
在这段代码中foo是直接使用了不带任何修饰的函数引用进行调用的,所以使用了默认绑定,即作为全局对象window的方法来进行调用的,可以看作window.foo();所以这里是window对象调用了foo这个方法,也就是说foo函数当中的this是指向window,同时window还具有了一个属性x,值为1。
var x = 1; function foo(){ console.log(this.x); } foo(); // 1
这里为了证明this是全局变量,进行了一下小改变。一开始定义的全局变量x作为window的属性,在调用时,this肯定是指向全局对象window。
但是在严格模式下,则不能将全局对象用于默认绑定,因此this会绑定到undefined。
function foo(){ "use strict"; console.log(this.x); } var x = 1; foo(); // Uncaught TypeError: Cannot read property 'x' of undefined
虽然this的绑定规则完全取决于调用位置,但是只有foo()运行在非严格模式下时,默认绑定才能绑定到全局对象。
作为对象方法的调用
var obj = { x : "1", foo: function() { console.log(this.x); } }; obj.foo(); // 1
这里的this指向的是对象obj,因为你调用这个foo是通过obj.foo()执行的,那this就指向就是对象obj。再次强调,this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式,谁调用的就指向谁,这个很重要。
作为构造函数来调用
function foo(){ this.x = 1; } var obj = new foo(); console.log(obj.x); // 1
这里可以实现输出1是因为new关键字可以改变this的指向,将this指向了obj对象。在传统的面向类语言中的new与js的new机制有着很多不同。在js中,构造函数只是使用new操作符时被调用的函数,不属于某个类,也不会实例化一个类,只是被new操作符调用的普通函数。new是可以影响函数调用时this绑定行为的方法,称之为new绑定。
使用apply/call方法来调用
function foo(){ console.log(obj.x); } var obj = { x:2 }; 4000 foo.call(obj); // 2
通过foo.call(),调用foo时将this绑定在了obj上。从this绑定的角度上,call()和apply()是一样的。如果你把null或者undefined作为this绑定的对象传入call,apply或者bind,在调用时会被忽略,执行的是默认绑定规则。
最后
如果要判断一个运行中的函数的this指向,就需要找到这个函数直接调用的位置。即谁调用这个函数或者方法,this就指向谁。this虽然只是js里的一小部分,对于我们学习者而言还是很重要的。this还有很多奥秘等着我们去发掘,我也只是知晓了其冰山一角,希望能分享一点自己的想法给一起学习路上的同学们,与君共勉。
参考
《你不知道的javascript》Javascript的this用法
相关文章推荐
- (转)腾讯微信技术总监周颢:一亿用户增长背后的架构秘密
- @Override标签背后的小秘密---记录java的思行合一(作者:leeon)
- 电商Banner设计背后的12个人性的秘密
- 腾讯微信技术总监周颢:一亿用户增长背后的架构秘密
- 揭开应用推广运营背后的秘密
- 总结程序员的技能杀伤力:程序员高薪背后的秘密
- 一亿用户增长背后的架构秘密
- 揭开应用推广运营背后的秘密
- 华尔街热捧金融科技,中国互金企业赴美上市潮背后的秘密
- 解读服务器命名规则背后的秘密
- 【一些事晚报】小米5发布会背后的5个小秘密
- 网上邻居背后的秘密——NetBIOS与SMB协议概览
- 中国电信屏蔽Google背后的秘密
- 暴风科技背后的秘密:不可忽视的华为因素
- @Override标签背后的小秘密---记录java的思行合一(作者:leeon)
- 移动设备界面设计之:显示屏背后的秘密
- 随机数字生成器(RNG)和Hash函数组合武器背后的黑暗秘密
- 隐藏在QRCode二维码背后的秘密
- 浅析2017年双十一数据,为你揭秘这些巨额成交量背后的秘密。