作者:sunshine小小倩
链接:https://juejin.im/post/59bfe84351882531b730bac2
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者:sunshine小小倩
链接:https://juejin.im/post/59bfe84351882531b730bac2
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
var name = "windowsName"; | |
function a() { | |
var name = "Cherry"; | |
console.log(this.name); // windowsName | |
console.log("inner:" + this); // inner: Window | |
} | |
a(); | |
console.log("outer:" + this) // outer: Window | |
/* | |
这个相信大家都知道为什么 log 的是 windowsName,因为根据刚刚的那句话 | |
“this 永远指向最后调用它的那个对象”,我们看最后调用 a 的地方 a(); | |
前面没有调用的对象那么就是全局对象 window,这就相当于是 window.a(); | |
注意,这里我们没有使用严格模式,如果使用严格模式的话,全局对象就是 undefined, | |
那么就会报错 Uncaught TypeError: Cannot read property 'name' of undefined。 | |
作者:sunshine小小倩 | |
链接:https://juejin.im/post/59bfe84351882531b730bac2 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | |
*/ |
var name = "windowsName"; | |
var a = { | |
name: "Cherry", | |
fn : function () { | |
console.log(this.name); // Cherry | |
} | |
} | |
a.fn(); | |
/* | |
在这个例子中,函数 fn 是对象 a 调用的,所以打印的值就是 a 中的 name 的值。 | |
作者:sunshine小小倩 | |
链接:https://juejin.im/post/59bfe84351882531b730bac2 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | |
*/ |
var name = "windowsName"; | |
var a = { | |
name: "Cherry", | |
fn : function () { | |
console.log(this.name); // Cherry | |
} | |
} | |
window.a.fn(); | |
/* | |
这里打印 Cherry 的原因也是因为刚刚那句话“this 永远指向最后调用它的那个对象”,最后调用它的对象仍然是对象 a。 | |
作者:sunshine小小倩 | |
链接:https://juejin.im/post/59bfe84351882531b730bac2 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | |
*/ |
var name = "windowsName"; | |
var a = { | |
// name: "Cherry", | |
fn : function () { | |
console.log(this.name); // undefined | |
} | |
} | |
window.a.fn(); | |
/* | |
这里为什么会打印 undefined 呢?这是因为正如刚刚所描述的那样,调用 fn 的是 a 对象, | |
也就是说 fn 的内部的 this 是对象 a,而对象 a 中并没有对 name 进行定义,所以 log | |
的 this.name 的值是 undefined。 | |
这个例子还是说明了:this 永远指向最后调用它的那个对象,因为最后调用 fn 的对象是 a, | |
所以就算 a 中没有 name 这个属性,也不会继续向上一个对象寻找 this.name, | |
而是直接输出 undefined。 | |
作者:sunshine小小倩 | |
链接:https://juejin.im/post/59bfe84351882531b730bac2 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | |
*/ |
var name = "windowsName"; | |
var a = { | |
name : "Cherry", | |
func1: function () { | |
console.log(this.name) | |
}, | |
func2: function () { | |
setTimeout( function () { | |
this.func1() | |
}, 100); | |
} | |
}; | |
a.func2() // Uncaught TypeError: this.func1 is not a function | |
/* | |
这里你可能会有疑问,为什么不是 Cherry,这是因为虽然将 a 对象的 fn 方法赋值给变量 f 了, | |
但是没有调用,再接着跟我念这一句话:“this 永远指向最后调用它的那个对象”,由于刚刚的 f | |
并没有调用,所以 fn() 最后仍然是被 window 调用的。所以 this 指向的也就是 window。 | |
在不使用箭头函数的情况下,是会报错的,因为最后调用 setTimeout 的对象是 window, | |
但是在 window 中并没有 func1 函数。 | |
匿名函数的 this 永远指向 window。 | |
作者:sunshine小小倩 | |
链接:https://juejin.im/post/59bfe84351882531b730bac2 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | |
*/ |
var name = "windowsName"; | |
function fn() { | |
var name = 'Cherry'; | |
innerFunction(); | |
function innerFunction() { | |
console.log(this.name); // windowsName | |
} | |
} | |
fn() | |
/* | |
这里的 innerFunction() 的调用是不是属于第一种调用方式:作为一个函数调用。 | |
它就是作为一个函数调用的,没有挂载在任何对象上,所以对于没有挂载在任何对象上 | |
的函数,在非严格模式下 this 就是指向 window 的。 | |
作者:sunshine小小倩 | |
链接:https://juejin.im/post/59bfe84351882531b730bac2 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | |
*/ |
var name = "windowsName"; | |
var a = { | |
name : "Cherry", | |
func1: function () { | |
console.log(this.name) | |
}, | |
func2: function () { | |
setTimeout( () => { | |
this.func1() | |
}, 100); | |
} | |
}; | |
a.func2() // Cherry | |
/* | |
众所周知,ES6 的箭头函数是可以避免 ES5 中使用 this 的坑的。箭头函数的 this | |
始终指向函数定义时的 this,而非执行时。箭头函数需要记着这句话:“箭头函数中没有 | |
this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 | |
this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined”。 | |
作者:sunshine小小倩 | |
链接:https://juejin.im/post/59bfe84351882531b730bac2 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | |
*/ |
var name = "windowsName"; | |
var a = { | |
name : "Cherry", | |
func1: function () { | |
console.log(this.name) | |
}, | |
func2: function () { | |
var _this = this; | |
setTimeout( function() { | |
_this.func1() | |
}, 100); | |
} | |
}; | |
a.func2() // Cherry | |
/* | |
如果不使用 ES6,那么这种方式应该是最简单的不会出错的方式了,我们是先将调用 | |
这个函数的对象保存在变量 _this 中,然后在函数中都使用这个 _this,这样 | |
_this 就不会改变了。 | |
作者:sunshine小小倩 | |
链接:https://juejin.im/post/59bfe84351882531b730bac2 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | |
*/ |
var a = { | |
name : "Cherry", | |
func1: function () { | |
console.log(this.name) | |
}, | |
func2: function () { | |
setTimeout( function () { | |
this.func1() | |
}.apply(a), 100); | |
} | |
}; | |
a.func2() // Cherry |
var a = { | |
name : "Cherry", | |
func1: function () { | |
console.log(this.name) | |
}, | |
func2: function () { | |
setTimeout( function () { | |
this.func1() | |
}.call(a), 100); | |
} | |
}; | |
a.func2() // Cherry |
var a = { | |
name : "Cherry", | |
func1: function () { | |
console.log(this.name) | |
}, | |
func2: function () { | |
setTimeout( function () { | |
this.func1() | |
}.bind(a)(), 100); | |
} | |
}; | |
a.func2() // Cherry |
var a ={ | |
name : "Cherry", | |
fn : function (a, b) { | |
console.log(a + b) | |
} | |
} | |
var b = a.fn; | |
b.apply(a, [1,2]) // 3 |
var a ={ | |
name : "Cherry", | |
fn : function (a,b) { | |
console.log( a + b) | |
} | |
} | |
var b = a.fn; | |
b.call(a,1,2) // 3 |
var a ={ | |
name : "Cherry", | |
fn : function (a, b) { | |
console.log(a + b) | |
} | |
} | |
var b = a.fn; | |
b.bind(a, 1, 2) |
var a ={ | |
name : "Cherry", | |
fn : function (a,b) { | |
console.log( a + b) | |
} | |
} | |
var b = a.fn; | |
b.bind(a,1,2)() // 3 |
var name = 'globalName'; | |
const obj = { | |
name: 'myName', | |
sayName: function () { console.log(this.name);} | |
} | |
obj.sayName(); | |
// output: myName | |
const say = obj.sayName; | |
// we are merely storing the function the value of this isn't magically transferred | |
say(); | |
// output: globalName | |
// now because this function is executed in global scope this will refer to the global var | |
const boundSay = obj.sayName.bind(obj); | |
// now the value of this is bound to the obj object | |
boundSay(); | |
// output: myName | |
// Now this will refer to the name in the obj object: 'myName' | |
// what happened? | |
// `.bind` is creating a new function, with a fixed context | |
console.log(boundSay == obj.sayName) | |
// output: false | |
// reading | |
// 1. https://stackoverflow.com/questions/2236747/use-of-the-javascript-bind-method | |
// 2. https://gist.github.com/zcaceres/2a4ac91f9f42ec0ef9cd0d18e4e71262 |