js的this指向
规则1:使用new后this指向new创建的对象
function __new() { this.a = "测试" console.log(this) } var a = new __new()
这个就是new 构造创建的对象,this指向它
规则2:使用call 或者apply this指向你传入的对象 这里传入的对象不能为null、undefined 不然指向window
function aa() { console.log(this) console.log(this.a) } var b = { a: '我是b对象' } aa.call(b)
//aa.apply(b)
规则3: this指向 函数最后被调用位置
function a(x) { console.log(this) console.log(this === x) } var b = { c: a } b.c(b) //可理解为a在b中被调用执行了,调用的位置是b,this指向b
var c = { dd: { a:function(x) { console.log(this === x) } } } c.dd.a(c) c.dd.a(c.dd) //这才是真正的调用位置
默认: this指向全局(window)对象 严格模式下指向undefined
function aa() { function bb(){ console.log(this) console.log(this === window) } bb() } aa()/*和下面一样*/// function aa() { // bb() // } // function bb(){ // console.log(this) // console.log(this === window) // } // aa()
来个规则用法图:
看看这个例子:
function foo() { console.log(this) console.log(this === window) } var bar = { aa: foo } foo() bar.aa() var zz = bar.aa zz()
用规则套第一个结果和第二个结果很容易就出来。这里分析zz()的this为什么指向window?this绑定丢失了?是规则错了吗?
先看看这个两个例子
例子1:
var aa = 1 var bb = aa bb += 1 console.log(aa) console.log(bb)
例子2:
var a = { b: 1 } var c = a
console.log(c)
c.b = 2
console.log(a.b)
结果 a.b 变成2了,出乎意料
第一种给bb赋值的方式是把aa复制了一份在给bb所以对bb操作不会对aa产生任何影响
第二种是 把 a指向{b: 1}这个对象的引用 赋值给了c 。这个时候也就是a和c都指向了{b: 1}
出现这两种情况的原因是由于js对赋值的机制,赋值/传递方式由“等号右边决定”
对于对象(包括数组和封装对象)和函数,则总是通过引用复制的方式来赋值/传递,
其他null、undefined、字符串、数字、布尔和ES6中的symbol 则是通过值复制/传递
所以说上面 得到bar.aa是一个function.所以这里采用引用赋值/传递
zz等于直接指向了
也就是var zz = foo 那么这里的话就是用默认规则了 this指向window对象
这里值得注意的是在es6中 箭头函数是没有this的 箭头函数里面的this是它把箭头函数外面的(或说为箭头函数所在位置的)this给“抓”进来了
var c = { dd: { a:(x) => { console.log(this === x) }, b:this } } c.dd.a(c) c.dd.a(c.dd.b) c.dd.a(c.dd) console.log("--------------") function aa(){ this.a = 1 var b = this console.log(b); (() => { console.log(this === b) })() } var qaq = new aa()
------------------------------------------------如果有理解错误的地方 请指正一下啊 QAQ~