摘要:的绑定规则默认绑定像严格模式下等价于非严格模式下等价于全局对象这个全局对象在浏览器中是,中是隐氏绑定像等价于,作为一个上下文对象隐性传递到了中这个传递是隐性的,我们观察不到的。
用call来解释this很形象,但是不是那么严谨,详情看补充1;
了解this的本质比较严谨的解释:一个函数可以在多个环境中执行,函数执行时允许访问环境中的其他变量,this会指向调用函数的那个环境;
比较易懂的解释:
函数调用时都指定了它的外部环境,这里用call来展示外部环境:
fn(x);,可以理解为fn.call(undefined,x);这里fn中的this就是undefined;
obj.fn(); 可以理解为obj.fn.call(obj,x);这里fn中的this就是obj;
call函数的第一个参数就是指定的外部环境,就是this
想要知道一个函数中的this是谁,大部分情况下可以去函数调用栈中找上一个函数看到。
1.默认绑定
像fn();
严格模式下等价于fn.call(undefined);
非严格模式下等价于fn.call(全局对象);这个全局对象在浏览器中是window,node中是global;
2.隐氏绑定
像obj.fn();等价于fn.call(obj),obj作为一个上下文对象隐性传递到了fn中;
这个传递是隐性的,我们观察不到的。
3.显示绑定
像fn.call(context); fn在执行时,this就是context;
这个绑定很明显,是我们可以观察、并且控制的。
显示绑定很常用,这里贴一个bind方法的极简实现
function bind(fn, obj) { return function() { return fn.apply( obj, arguments ); }; }
4.new绑定
js中的new操作符和其他语言的new机制完全不一样。
new执行的操作用伪代码表达一下:
// 执行new Foo()时发生的操作 var obj = {}; // 创建空对象 obj.__proto__ = Foo.prototype; // 连接到foo的原型,继承机制 Foo.call(obj); // 绑定成上下文,并执行foo return obj; // foo中如果没有return的话,return obj这个对象回去补充1:this被忽略的情况,用call做例子不严谨的原因
当把null或undefined作为this传入call、apply、bind时,实际应用的是默认绑定规则;
// 非严格模式 function foo() { console.log( this.a ); } var a = 2; foo.call( null ); // 2补充2:一个结合this、声明提升、全局局部变量的例子:
var a=10; function test(){ a=5; alert(a); alert(this.a); var a; alert(this.a); alert(a); } 执行test()和new test() 结果是什么 答案: alert的内容:test(): 5,10,10,5 new test():5,undefined,undefined,5补充3:this丢失(优先级)
// 用一个简单的例子开个头 // obj.fn是一种隐性绑定,将fn中的this指向obj // 但是this又被context覆盖了,这种this丢失可以引申出优先级的问题。 obj.fn.call(context)补充4:箭头函数
箭头函数的this继承上层函数
var obj = { say: function () { setTimeout(() => { console.log(this) //obj }, 0) } }补充5
立即执行函数执行时,obj还是undefined
var obj = { say: function () { function _say() { console.log(this) //window or global } return _say.bind(obj) }() } obj.say()补充6
var length = 10; function fn() { console.log(this.length); } var obj = { length: 5, method: function(fn) { fn(); arguments[0](); // arguments.0() } }; obj.method(fn, 1); // 10 2补充7
var a=10; var foo={ a:20, bar:function(){ var a=30; return this.a; } } foo.bar() (foo.bar)() (foo.bar=foo.bar)() (foo.bar,foo.bar)() // 20 20 10 10补充8
var num = 1; function codequn(){ "use strict"; console.log("codequn: ",this.num++); } function codequn2(){ console.log("codequn2: ",++this.num); } (function(){ "use strict"; codequn2(); })(); codequn(); // codequn2: 2 // Cannot read property "num" of undefined补充9
箭头函数中的this是定义时所在对象的this,而不是执行时
const debounce = function(fn, time) { let timeout = null return function() { const _self = this clearTimeout(timeout) timeout = setTimeout(()=>{ console.log(this === _self) //true fn.call(this, ...arguments) }, time) } }
参考:
《你不知道的javascript上卷》;
https://www.zhihu.com/questio...;
http://www.ruanyifeng.com/blo...;
https://developer.mozilla.org...;
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/103246.html
摘要:首先设置侵入状态栏,并设置状态栏为透明色,相当于隐藏的状态栏,然后在中封装状态栏,由控制自己的颜色即可但是状态栏字体颜色还是需要通过控制。 目录介绍 1.关于如何集成 2.关于如何使用 3.关于鸣谢 4.关于版本更新说明 5.关于其他介绍 0.说明 状态栏工具类,应该可以满足绝大多数的使用场景。具体可以参考代码案例,欢迎star!! 1.技术博客汇总 2.开源项目汇总 3.生...
摘要:关于提供了一种优雅的方式来隐式传递一个对象引用,因此可以将设计得更加简洁并且易于复用。对于的误解新手会误认为指向函数本身。这时候,可以使用的方法强制使指向函数对象。的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。 关于this this 提供了一种优雅的方式来隐式传递一个对象引用,因此可以将API设计得更加简洁并且易于复用。 /* *this 隐式传递...
摘要:中指向问题一直是个坑,之前一直是懵懵懂懂的,大概知道一点,但一直不知道各种情况下指向有什么区别,今天亲自动手测试了下的指向。这就是我关于学习的总结,希望能给需要的人点帮助,然后有啥不足希望有大神能指点出来。 js中this指向问题一直是个坑,之前一直是懵懵懂懂的,大概知道一点,但一直不知道各种情况下指向有什么区别,今天亲自动手测试了下this的指向。 1.在对象中的this对象中的t...
摘要:中指向问题一直是个坑,之前一直是懵懵懂懂的,大概知道一点,但一直不知道各种情况下指向有什么区别,今天亲自动手测试了下的指向。这就是我关于学习的总结,希望能给需要的人点帮助,然后有啥不足希望有大神能指点出来。 js中this指向问题一直是个坑,之前一直是懵懵懂懂的,大概知道一点,但一直不知道各种情况下指向有什么区别,今天亲自动手测试了下this的指向。 1.在对象中的this对象中的t...
摘要:另外,的绑定和函数声明的位置没有任何关系,之取决于函数的调用方式。请看下面代码这样,我们就可以在调用的时候强制把它的绑定到上绑定在传统的面向类语言中,使用初始化类时会调用类中的构造函数。 关于this 上一章我们讲了关于作用域和闭包的相关知识,现在开始新一轮的学习,那就是JavaScript中最复杂的机制之一---this关键字。它是一个很特别的关键字,被自动定义在所有函数的作用域中。...
阅读 2679·2023-04-25 20:28
阅读 1849·2021-11-22 09:34
阅读 3687·2021-09-26 10:20
阅读 1834·2021-09-22 16:05
阅读 3085·2021-09-09 09:32
阅读 2502·2021-08-31 09:40
阅读 2099·2019-08-30 13:56
阅读 3320·2019-08-29 17:01