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
this是一个很特别的关键字,被自动定义在所有函数的作用域中。
this既不指向函数自身也不指向函数的词法作用域。
this是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
this 绑定规则优先级:new > call(..) 或者 apply(..) > 上下文对象调用 > 默认绑定
call(..)
apply(..)
调用栈:为了到达当前执行位置所调用的所有函数。 调用位置在当前正在执行的函数的前一个调用中。
function baz() { // 当前调用栈是:baz // 因此,当前调用位置是全局作用域 console.log("baz"); bar(); // <-- bar的调用位置 } function bar() { // 当前调用栈是 baz -> bar // 因此,当前调用位置在baz中 console.log("bar"); foo(); // <-- foo的调用位置 } function foo() { // 当前调用栈是 baz -> bar -> foo // 因此,当前调用位置在bar中 console.log("foo"); } baz(); // <-- baz的调用位置
注意我们是如何(从调用栈中)分析出真正的调用位置的,因为它决定了 this 的绑定。
默认绑定
var a = 2; function foo() { console.log(this.a); } foo(); // 2
独立函数调用,既使用不带任何修饰的函数引用进行调用,无法应用其他规则。非 static mode 下,this 默认绑定全局对象。strict mode 下,this 默认绑定 undefined。
隐式绑定
function foo() { console.log(this.a); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
当函数引用有上下文对象时,隐私绑定规则会把函数调用中的 this 绑定到这个上下文对象。
显示绑定
call(..) apply(..) bing(..)
bing(..)
function foo() { console.log(this.a); } var obj = { a: 2 }; foo.call(obj) // 2
通过 foo.call(..),我们可以在调用foo时强制把它的 this 绑定到 obj 上。
foo.call(..)
foo
如果传入了一个原始值(字符串类型、布尔类型、数字类型)来当作 this 的绑定对象,这个原始值会被转换成它的对象形式(也就是 new String(..)、new Boolean(..)、new Number(..) )。
从 this 绑定的角度来说,call(..) 和 apply(..) 是一样的,它们区别体现在其他的参数上。
new绑定
使用 new 来调用函数,会自动执行下面的操作 创建(构造)一个全新的对象。 这个新对象会被执行[[原型]]连接。 这个新对象会绑定到函数调用的this。 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。
使用 new 来调用函数,会自动执行下面的操作
function foo(a) { this.a = a; } var bar = new foo(2); console.log( bar.a ); //2
使用 new 来调用 foo(..) 时,我们会构造一个新对象并把它绑定到foo(..)调用中的 this 上。new 是最后一种可以影响函数调用时 this 绑定行为的方法。
foo(..)
绑定例外
如果你把null 或者 undefined 作为 this 的绑定对象传入 call, apply 或者 bind,这些值在调用时会被忽略,实际应用的是默认绑定规则。
null
undefined
function foo() { console.log(this.a); } var a = 2; foo.call( null ); // 2
bing(..) 可以对参数进行柯里化(预先设置一些参数)。
function foo(a,b) { console.log("a:" + a + ",b:" + b); } // 把数组“展开”成参数 foo.apply(null,[2,3]); // a:2, b:3 // 使用 bind(..) 进行柯里化 var bar = foo.bind(null, 2); bar(3); // a:2, b:3
这两种方法都需要传入一个参数当作 this 的绑定对象。如果函数并不关心 this 的话,你仍然需要传入一个占位值,这时 null 可能是一个不错的选择。
总是使用 null 来忽略 this 绑定可能产生一些副作用。如果某个函数确实使用了 this (比如第三方库中的一个函数),那默认绑定规则会把 this 绑定到全局对象(在浏览器中这个对象是window),这将导致不可预计的后果(比如修改全局对象)。
更安全的this
function foo(a,b) { console.log("a:" + a + ",b:" + b); } // 我们的 DMZ 空对象 var o = Object.create( null ); // 把数组展开成参数 foo.apply(o , [2,3]); // a:2, b:3 // 使用 bind(..) 进行柯里化 var bar = foo.bind(o, 2); bar(3); // a:2, b:3
在 JavaScript 中创建一个空对象最简单的方法都是 Object.create(null)。Object.create(null) 和 {} 很像,但是并不会创建 Object.prototype 这个委托,所以它比 {} "更空"。
JavaScript
Object.create(null)
Object.prototype
箭头函数不使用 this 的四种标准规则,而是根据外层(函数或者全局)作用域来决定 this。
function foo() { //返回一个箭头函数 return (a) => { // this 继承自 foo() console.log(this.a); }; } var obj1 = { a: 2 }; var obj2 = { a: 3 } var bar = foo.call( obj1 ); bar.call( obj2 ); // 2,不是 3 !
The text was updated successfully, but these errors were encountered:
No branches or pull requests
this是一个很特别的关键字,被自动定义在所有函数的作用域中。
this既不指向函数自身也不指向函数的词法作用域。
this是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
this 绑定规则优先级:new >
call(..)
或者apply(..)
> 上下文对象调用 > 默认绑定调用位置
注意我们是如何(从调用栈中)分析出真正的调用位置的,因为它决定了 this 的绑定。
绑定规则
默认绑定
独立函数调用,既使用不带任何修饰的函数引用进行调用,无法应用其他规则。非 static mode 下,this 默认绑定全局对象。strict mode 下,this 默认绑定 undefined。
隐式绑定
当函数引用有上下文对象时,隐私绑定规则会把函数调用中的 this 绑定到这个上下文对象。
显示绑定
call(..)
apply(..)
bing(..)
通过
foo.call(..)
,我们可以在调用foo
时强制把它的 this 绑定到 obj 上。如果传入了一个原始值(字符串类型、布尔类型、数字类型)来当作 this 的绑定对象,这个原始值会被转换成它的对象形式(也就是 new String(..)、new Boolean(..)、new Number(..) )。
new绑定
使用 new 来调用
foo(..)
时,我们会构造一个新对象并把它绑定到foo(..)
调用中的 this 上。new 是最后一种可以影响函数调用时 this 绑定行为的方法。绑定例外
被忽略的this
如果你把
null
或者undefined
作为 this 的绑定对象传入 call, apply 或者 bind,这些值在调用时会被忽略,实际应用的是默认绑定规则。bing(..) 可以对参数进行柯里化(预先设置一些参数)。
这两种方法都需要传入一个参数当作 this 的绑定对象。如果函数并不关心 this 的话,你仍然需要传入一个占位值,这时 null 可能是一个不错的选择。
总是使用 null 来忽略 this 绑定可能产生一些副作用。如果某个函数确实使用了 this (比如第三方库中的一个函数),那默认绑定规则会把 this 绑定到全局对象(在浏览器中这个对象是window),这将导致不可预计的后果(比如修改全局对象)。
更安全的this
在
JavaScript
中创建一个空对象最简单的方法都是Object.create(null)
。Object.create(null)
和 {} 很像,但是并不会创建Object.prototype
这个委托,所以它比 {} "更空"。箭头函数
箭头函数不使用 this 的四种标准规则,而是根据外层(函数或者全局)作用域来决定 this。
The text was updated successfully, but these errors were encountered: