用call来解释this很形象,可是不是那么严谨,详情看补充1;javascript
比较严谨的解释:一个函数能够在多个环境中执行,函数执行时容许访问环境中的其余变量,this会指向调用函数的那个环境;html
比较易懂的解释:java
call函数的第一个参数就是指定的外部环境,就是this
想要知道一个函数中的this是谁,大部分状况下能够去函数调用栈中找上一个函数看到。node
1.默认绑定浏览器
2.隐氏绑定app
3.显示绑定函数
function bind(fn, obj) { return function() { return fn.apply( obj, arguments ); }; }
4.new绑定this
// 执行new Foo()时发生的操做 var obj = {}; // 建立空对象 obj.__proto__ = Foo.prototype; // 链接到foo的原型,继承机制 Foo.call(obj); // 绑定成上下文,并执行foo return obj; // foo中若是没有return的话,return obj这个对象回去
// 非严格模式 function foo() { console.log( this.a ); } var a = 2; foo.call( null ); // 2
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
// 用一个简单的例子开个头 // obj.fn是一种隐性绑定,将fn中的this指向obj // 可是this又被context覆盖了,这种this丢失能够引伸出优先级的问题。 obj.fn.call(context)
箭头函数的this继承上层函数prototype
var obj = { say: function () { setTimeout(() => { console.log(this) //obj }, 0) } }
当即执行函数执行时,obj仍是undefinedcode
var obj = { say: function () { function _say() { console.log(this) //window or global } return _say.bind(obj) }() } obj.say()
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
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
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
箭头函数中的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...;