this的绑定规则有4种
- 默认绑定
- 隐性绑定
- 显性绑定
- new绑定
this绑定优先级
new 绑定 > 显性绑定 > 隐性绑定 > 默认绑定
1.如果函数被new 修饰
this绑定的是新创建的对象,例:var bar = new foo(); 函数 foo 中的 this 就是一个叫foo的新创建的对象 , 然后将这个对象赋给bar , 这样的绑定方式叫 new绑定 .
2.如果函数是使用call,apply,bind来调用的
this绑定的是 call,apply,bind 的第一个参数.例: foo.call(obj); , foo 中的 this 就是 obj , 这样的绑定方式叫 显性绑定 .
3.如果函数是在某个 上下文对象 下被调用
this绑定的是那个上下文对象,例 : var obj = { foo : foo }; obj.foo(); foo 中的 this 就是 obj . 这样的绑定方式叫 隐性绑定 .
4.如果都不是,即使用默认绑定
例:function foo(){...} foo() ,foo 中的 this 就是 window.(严格模式下默认绑定到undefined).这样的绑定方式叫 默认绑定 .
例:function foo(){...} foo() ,foo 中的 this 就是 window.(严格模式下默认绑定到undefined).这样的绑定方式叫 默认绑定 .
其实除了默认绑定容易出现理解问题,其他3中都还好,下面来看下默认绑定的一些情况。
重点是要理解:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
var length = 10
var obj = {
length: 5,
method: function(){
console.log(this.length)
}
}
obj.method()
// 这种情况很简单,没啥问题,输出5
var length = 10;
function fn() {console.log(this.length)}
var obj = {
length: 5,
method: function(fn){
fn();
arguments[0]();
}
}
obj.method(fn);
obj.method(fn,123)
// 输出:
// 10
// 1
// 10
// 2
上面这道题比较坑的是 length是JavaScript内置的属性。
通过传参进去,调用的时候,调用它的对象是window。
通过arguments0调用的时候,调用fn的对象是arguments,输出的是arguments的内置属性length
情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。
情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
https://www.cnblogs.com/pssp/p/5216085.html
var value = 1;
var foo = {
value: 2,
bar: function () {
return this.value;
}
}
console.log((false || foo.bar)())
逻辑运算符通常用于布尔型(逻辑)值。这种情况下,它们返回一个布尔值。然而,&& 和 || 运算符会返回一个指定操作数的值,因此,这些运算符也用于非布尔值。这时,它们也就会返回一个非布尔型值。
所以,相当于foo.bar 赋值给了一个变量,然后再调用