We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
var a = 2; function foo(){ console.log(this.a); } function bar(){ var a = 5; foo(); } bar(); // 2
function foo() { console.log( this.a ); } var obj2 = { a: 42, foo: foo }; var obj1 = { a: 2, obj2: obj2 }; obj1.obj2.foo(); // 42
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; var bar = obj.foo; // 这里bar将引用foo函数本身,所以不带有函数对象的上下文 var a = "oops, global"; // a是全局对象的属性 bar(); // "oops, global"
和回调函数的情况下(参数传递时的隐式赋值)
function foo() { console.log( this.a ); } function doFoo(fn) { // 参数传递时,相当于fn = obj.foo,就和上个例子一样了 fn(); // <-- call-site! } var obj = { a: 2, foo: foo }; var a = "oops, global"; // `a` also property on global object doFoo( obj.foo ); // "oops, global"
function foo() { console.log( this.a ); } var obj = { a: 2 }; var bar = function() { foo.call( obj ); }; bar(); // 2 setTimeout( bar, 100 ); // 2 // 硬绑定后bar无论怎么调用,都不会影响foo函数的this绑定 bar.call( window ); // 2
硬绑定的典型应用是如下的包裹函数:
function foo(something) { console.log( this.a, something ); return this.a + something; } var obj = { a: 2 }; var bar = function() { return foo.apply( obj, arguments ); // 将obj对象硬编码进去 }; var b = bar( 3 ); // 2 3 console.log( b ); // 5
即将内部函数用apply硬绑定到某个对象,无论怎么调用这个包裹函数,都不会影响内部函数的this。 bind辅助函数如下:
function foo(something) { console.log( this.a, something ); return this.a + something; } // simple `bind` helper function bind(fn, obj) { return function() { return fn.apply( obj, arguments ); // 利用参数将obj传入进去 }; } var obj = { a: 2 }; var bar = bind( foo, obj ); // bind( foo, obj )会返回一个包裹函数 var b = bar( 3 ); // 2 3 console.log( b ); // 5
总结:上述包裹函数,想要包裹其他函数,只能一个一个重复写,硬编码的方式导致不能被重用,当某种功能需要多次重复使用时,将其抽象出来,成为函数。
function foo(a) { this.a = a; } var bar = new foo( 2 ); console.log( bar.a ); // 2
function foo() { console.log( this.a ); } var a = 2; var o = { a: 3, foo: foo }; var p = { a: 4 }; o.foo(); // 3 (p.foo = o.foo)(); // 2,由于p.foo = o.foo的返回值是目标函数的引用,所以调用位置是foo(),而不是p.foo()或o.foo()
function foo() { // 返回一个箭头函数 return (a) => { // `this` here is lexically adopted from `foo()` console.log( this.a ); }; } var obj1 = { a: 2 }; var obj2 = { a: 3 }; // foo()不是箭头函数,他的this被绑定到obj1 var bar = foo.call( obj1 ); // foo.call( obj1 )返回箭头函数,所以bar为箭头函数 bar.call( obj2 ); // 2! 箭头函数的this无法被修改,new也不行
如下为和箭头函数一样的模式:
function foo() { var self = this; // lexical capture of `this` setTimeout( function(){ console.log( self.a ); }, 100 ); } var obj = { a: 2 }; foo.call( obj ); // 2
知乎链接-arguments对象调用
The text was updated successfully, but these errors were encountered:
No branches or pull requests
this
为什么要使用this:使API设计得更简洁且易于复用。
this即不指向自身,也不指向函数的词法作用域。
this的指向只取决于函数的调用方式
this绑定规则
默认绑定
隐式绑定
和回调函数的情况下(参数传递时的隐式赋值)
显式绑定
硬绑定的典型应用是如下的包裹函数:
即将内部函数用apply硬绑定到某个对象,无论怎么调用这个包裹函数,都不会影响内部函数的this。
bind辅助函数如下:
总结:上述包裹函数,想要包裹其他函数,只能一个一个重复写,硬编码的方式导致不能被重用,当某种功能需要多次重复使用时,将其抽象出来,成为函数。
new绑定
1. 创建一个新对象(若该函数不是JS内置的,则创建一个新的Object对象);
2. 将this绑定到这个对象;
3. 执行构造函数中的代码(为这个新对象添加属性);
4. 若函数没有返回其他对象,则自动返回这个新对象;若函数有return返回的是非对象,则还是自动返回这个新对象,即覆盖那个非对象。
补充说明
如下为和箭头函数一样的模式:
this绑定的趣题:
知乎链接-arguments对象调用
The text was updated successfully, but these errors were encountered: