全局中的代码无论是否处于严格模式下,它的this都执行Windowjavascript
console.log(this) // Window
复制代码
() => {
console.log(this) // window 或 global,在全局定义指向全局
}
obj = {
fn: () => {
console.log(this) // obj 在obj对象中定义,可是指向全局(箭头函数时,obj没法确认环境)
}
}
复制代码
直接调用函数(在全局或者其余函数内)html
在非严格模式下,this默认指向全局变量(window或global)java
```js
// 在浏览器中,全局对象是window, 在NODE中是global
function test() {
console.log(this) // Window 或者 global
(function(){
console.log(this) // Window 或者 global
})
}
test()
```
复制代码
function test() {
console.log(this) // undefined
(function(){
console.log(this) // undefined
})
}
test()
复制代码
// setTimeout是window的方法,可使用window.setTimeout调用
// 调用函数时,对象访问大体路线:window -> setTimeout -> 获取参数中test的引用参数 -> 执行 test 函数
function test() {
console.log(this)
}
setTimeout(test, 100); // window 或 global
复制代码
做为对象方法调用则指向当前对象es6
var a = 'global'
function name() {
console.log('name', this.a) // 经过普通调用方法直接调用,在严格模式下this为undefined,运行报错,在非严格模式下global
}
var obj = {
fn: function () {
console.log('inner', this.a) // obj 经过对象obj调用,this指向该对象与模式没有关系
name()
},
a: 'obj'
}
obj.fn()
var newFn = obj.fn()
newFn() // 严格模式为undefined,非严格为window或者global,按普通方法直接调用的规则处理
function test(fn){
fn()
}
test(obj.fn) // 至关于将fn=obj.fn, 严格模式为undefined,非严格为window或者global
newObj = {fn: 2}
test(newObj.fn=obj.fn) // 至关于 fn = newObj.fn = obj.fn, 严格模式为undefined,非严格为window或者global
复制代码
执行new操做时,构造函数的this指向正在构造的新对象浏览器
function TEST(){
this.a = 'obj';
console.log(this) //new操做时 TEST { a: 'obj'} this指向正在构造的对象(返回的对象)
}
var o = new TEST();
console.log(o); // TEST { a: 'obj'} this指向刚刚构造的对象
复制代码
class MyTest {
constructor (callback) {
this.callback = callback
callback() // 指向window
}
func () {
this.callback() // 指向MyTest
}
}
// let的值不会绑定到window上,没法用window.name访问
let name = 'global'
function Test () {
console.log(this, this.name)
}
new Test() // window 使用let输出 '', 使用var输出global
let c = new MyTest(Test) // window 使用let输出 '', 使用var输出global
c.func() // MyTest{} undefined
复制代码
// 当函数直接调用的时候,在非严格模式下,this指向window;严格模式为undefined
// 当函数做为对象的属性调用的时候,this指向这个对象;
// p1.constructor指向Person的构造函数(Person()函数自己),
// 在p1.constructor()时,Person是做为p1的属性调用的,因此this指向p1;
// 当调用p2 = p1.constructor;p2();时,其实就至关于直接调用Person();因此this指向window
var name = 'global'
function Person() {
this.name = 'person';
console.log(this);
}
var p1 = new Person();
p1.constructor(); // Person {name: "person"}
var p2 = p1.constructor;
p2(); // window
复制代码
设置call/apply/bind后调用,则指向其第一个参数的this,若是为空则在严格模式下指向undefined,在非严格模式下指向window或globalbash
// 语法
// 一、函数.apply(对象, [参数列表])
// 二、函数.call(对象, arg1,arg2,arg3…argn)
// 三、函数.bind(对象)
// 'use strict'
var a = 'global'
function name() {
console.log('name', this.a)
}
function name2() {
console.log('name2', this)
}
var obj = {
a: 'obj'
}
name.call(obj) // obj this指向经过call绑定的obj对象
// name2.call() // 严格模式为undefined,非严格模式为widow或global
复制代码
做为一个dom事件处理函数,它的this指向添加处理事件的元素(一些浏览器在使用非addEventListener的函数动态添加监听函数时不遵照这个约定)闭包
// html
<div id="A">
<div id="B"></div>
</div>
// javascript
var a = document.getElementById('A');
var b = document.getElementById('B');
function logs (e) {
console.log(e.target, e.target===this); // 当e.target与e.currentTarget相等时为true
console.log(e.currentTarget, e.currentTarget===this); // 老是true
}
a.addEventListener('click', logs, false);
// 点击A时,
// 输出 A节点信息,true \n A节点信息, true
// 点击B时,
// 输出 B节点信息,false \n A节点信息, true
// currentTarget表示实际绑定处理事件的元素
// target表示触发事件的元素(如点击B)
// 因此处理事件中的this指向实际添加处理事件的元素
复制代码
做为一个内联事件处理函数,app
<button onclick="alert(this.tagName.toLowerCase());">Show this</button>
复制代码
<button onclick="alert((function(){return this})());">Show inner this</button>
复制代码
闭包的执行至关因而返回一个函数,而后将这个返回的函数执行,所以和普通函数的直接调用相同dom
var box={
user: 'zs',
getThis:function(){
return function(){
return this;
};
}
}
console.log(box.getThis()()); // 指向全局,非严格为window,严格为undefined
复制代码