Skip to content
New issue

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

JavaScript -- this关键字 #10

Open
mt51 opened this issue Oct 25, 2018 · 0 comments
Open

JavaScript -- this关键字 #10

mt51 opened this issue Oct 25, 2018 · 0 comments

Comments

@mt51
Copy link
Owner

mt51 commented Oct 25, 2018

this

this是执行上下文中的一个重要属性

  • 变量对象(Variable Object, VO)
  • 作用域链(Scope chain)
  • this

全局执行上下文中的this

在全局执行上下文中,this指向全局对象。

// 在浏览器中
console.log(this === window)   // true

函数上下文中的this

在函数内部,this的值取决于函数被调用的方式,同一个函数调用的方式不同this的值就可能不同

function foo () {
    console.log(this.a)
}
var a = 'global'
var obj = {
    a: 'local',
    foo: foo
}
obj.foo()  // local
foo()  // global
独立函数调用

此时,在非严格模式下,this指向全局对象,在严格模式下thisundefined

function foo () {
    return this
}
console.log(foo() === window)   // true

function bar () {
    'use strict'
    return this
}
console.log(bar())  // undefined
作为对象方法

当函数作为对象方法调用时,this指向调用该方法的对象。

var obj = {
    a: 'aaa',
    foo: function () {
        console.log(this.a)
    }
}
obj.foo()   // 'aaa'
var foo = obj.foo
foo() // undefined

当将一个函数的方法赋值给另外一个变量,然后通过变量去调用该方法时,此时属于作为独立函数调用,this的值会指向全局对象。

作为构造函数

当一个函数做为构造函数使用时,this执行构造函数返回的新对象。

var a = 'global'
function Foo () {
    this.a = 'local'
}
var foo = new Foo()
foo.a  // 'local'
修改this的指向
使用callapply

可以使用callapply来显示的修改this的指向

var a = 'global'
function foo () {
    console.log(this.a)
}
var obj = {
    a: 'obj'
}

var obj2 = {
    a: 'obj2'
}
foo.call(obj)  //  'obj'
foo.call(obj2)  //  'obj2'

如果给callapply传入一个null或者undefined

在非严格模式下this指向全局对象,在严格模式下this为传入的值。

var a = 'global'
function foo () {
    console.log(this.a)
}
function bar () {
    'use strict'
    console.log(this)
}

foo.call(null)  //  'global'

bar.call(null)  //  null

apply()call()的区别

apply()call()的作用相同都是用来显示的修改this的指向,在传递参数上有些区别:

//  apply
function foo (...args) {
    console.log(args)
    console.log(arguments)
}

foo.apply(null, [1, 2, 3])

foo.apply(null, 1, 2, 3)  // TypeError
//  call
function foo (...args) {
    console.log(args)
    console.log(arguments)
}
foo.call(null, [1, 2, 3])

foo.call(null, 1, 2, 3) 

上面两个例子可以看出:

  • apply() 在传递参数的时候必须使用数组或者类数组对象,apply()会将参数数组的每一个元素传入调用的函数中
  • call()则是传入一组参数列表
使用bind

bind(thisArg[arg1[,...]])

  • thisArg:传递给绑定函数的this参数,当使用new时该值被忽略
  • arg1,...:调用绑定函数时,这些参数会在实参之前传递给被绑定的函数

bind() 会返回一个新的函数,该函数中的this指向传入的值。

var a = 'global'
function foo () {
    console.log(this.a)
}
var obj = {
    a: 'local'
}
var tmpFoo = foo.bind(obj)
tmpFoo() // local

当使用 new 调用bind返回的函数时,this参数提供的值将会被忽略,此时this指向构造函数生成的实例

var a = 'global'
function foo () {
    this.a = '123'
}
var obj = {
    a: 'local'
}
var tmpFoo = foo.bind(obj)
var bar = new tmpFoo(obj)
bar.a  // '123'
function foo (name, age) {
    console.log('name:', name)
    console.log('age:', age)
}
var bar = foo.bind(null, 'name')
bar('age')
// 'name: name'
// 'age: age'
箭头函数中的this

ES6中引入了箭头函数,箭头函数不会创建自己的this,只会从自己的作用域链的上一层继承this

var a = 'global'
function foo () {
    var self = this
    setTimeout(function () {
        console.log(this.a)
        console.log(self.a)
    }, 0)
}
var obj = {
    a: 'local'
}
foo()  //  'global'  'global'
foo.call(obj) // 'global' 'local'
var a = 'global'
function foo () {
    var self = this
    setTimeout(() => {
        console.log(this.a)
        console.log(self.a)
    }, 0)
}
var obj = {
    a: 'local'
}
foo()  //  'global'  'global'
foo.call(obj) // 'local' 'local'

参考

MDN this

mqyqingfeng/Blog#12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant