If you want to determine what the rules are in this, there are several rules to determine what this is in the function. Determining what this is is actually very simple. The general rule is to determine this when a function is called by checking where it was called. It follows these rules, described next in order of priority.
Rules
1. If you use the new keyword when calling a function, then this in the function is a brand new object.
function ConstructorExample() { console.log(this); this.value = 10; console.log(this); } new ConstructorExample(); // -> {} // -> { value: 10 }
2. If you use apply, call or bind to call a function, then this in the function is the object passed in as a parameter.
function fn() { console.log(this); } var obj = { value: 5 }; var boundFn = fn.bind(obj); boundFn(); // -> { value: 5 } fn.call(obj); // -> { value: 5 } fn.apply(obj); // -> { value: 5 }
3. If the function is called as a method, that is, if the function is called using dot notation, then this is the object that has this function as an attribute. In other words, when a point is to the left of a function call, this is the object to the left of the point.
var obj = { value: 5, printThis: function() { console.log(this); } }; obj.printThis(); // -> { value: 5, printThis: ƒ }
4. If the function is called as a pure function, that is, it is called without any of the above conditions, then this is the global object. In a browser, this is the window object.
function fn() { console.log(this); } // 如果在浏览器里调用: fn(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}
Note that this rule is actually the same as the third rule. The difference is that functions not declared as methods will automatically become attributes of the global object window. Therefore, this is actually an implicit method call. When we call fn(), it will actually be understood by the browser as window.fn(), so this is window.
console.log(fn === window.fn); // -> true
5. If more than one of the above rules applies, the one with higher priority will set this value.
6. If it is an arrow function in ES2015, it will ignore all the above rules and receive the scope containing it as the value of this when it is created. To determine what this is, just go up one line from where you created the arrow function and see what this is there. The value of this in an arrow function is the same.
const obj = { value: 'abc', createArrowFn: function() { return () => console.log(this); } }; const arrowFn = obj.createArrowFn(); arrowFn(); // -> { value: 'abc', createArrowFn: ƒ }
Looking back at the third rule, when we call obj.createArrowFn(), this in createArrowFn is obj, because this is a method call. Therefore, obj will be bound to this in arrowFn. If we create an arrow function in the global scope, then the this value will be window.
Applying Rules
Let's look at a code example and apply these rules. Try it and see if you can figure out what this is in different function calls.
Determine which rule is applied
var obj = { value: 'hi', printThis: function() { console.log(this); } }; var print = obj.printThis; obj.printThis(); // -> {value: "hi", printThis: ƒ} print(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}
obj.printThis() belongs to the third rule, method call. On the other hand, print() falls under the fourth rule, a pure function call. For print(), we did not use new, bind/call/apply or dot notation when calling, so it corresponds to rule 4, this is the global object window.
When multiple rules are applied
When multiple rules are applied, the rule with higher priority in the list is used.
var obj1 = { value: 'hi', print: function() { console.log(this); }, }; var obj2 = { value: 17 };
If Rule 2 and Rule 3 apply at the same time, Rule 2 prevails.
obj1.print.call(obj2); // -> { value: 17 }
If Rule 1 and Rule 3 apply at the same time, Rule 1 prevails.
new obj1.print(); // -> {}
Library
Some libraries sometimes intentionally bind this value to certain functions. Usually the most useful value is bound to this in a function. For example, jQuery binds this to a DOM element and triggers an event in a callback. If a library has a this value that does not conform to the above rules, please read the documentation of the library carefully. It is likely to be bound using bind.
This object is bound based on the execution environment of the function when the function is running. Let me introduce to you a detailed analysis of the usage of this object in js. In fact, the essence of this sentence is that whoever calls the function, this will point to whom
Specifically speaking, there are usually the following situations:
Global function
In the global environment, this points to Window
//例子1 function A() { console.log(this) } A();//Window
The above example is very simple. Function A is executed in the global environment, which is the global object Window call function. At this time, this points to the Window
Object method
When called as an object method, this points to the object that calls the method
//例子2 var b = { getThis:function(){ console.log(this) } } b.getThis()//b
The examples we have given so far are relatively similar Simple and easy to understand, here comes an interesting one:
//例子3 var c = { getFunc:function(){ return function(){ console.log(this) } } } var cFun = c.getFunc() cFun()//Window
This example is different from the previous example. When running c.getFunc(), the first thing returned is an anonymous function. We assign this function to cFun , and then called cFun() in the global environment, so this still points to Window at this time.
What if we must return a c object here? We said at the beginning that the this object is determined when the function is executed. In Example 3, when c.getFunc() is executed, the this object still points to c, so we only need to keep this this. For the above The code has been slightly changed:
//例子4 var c = { getFunc:function(){ var that = this //在这里保留住this return function(){ console.log(that) } } } var cFun = c.getFunc() cFun()//c
This is why we can often see var self = this or var that = this in some codes.
call and apply
At this time, the this object usually points to the this value specified in the function (note the usual 2 words here, which are required in the exam)
call It’s a cliché to say “apply”, but I’ll introduce it a little bit, because I’m afraid new students may not have been exposed to it (in fact, it’s just to make up some words). Take call as an example, the syntax is like this
fun.call(thisArg, arg1, arg2, ...)
This How to use the method, see the following example:
//例子5 var d = { getThis:function(){ console.log(this) } } var e = { name:'e'//(给e写个`name`属性只是因为觉得孤零零的太难看了~~) } d.getThis.call(e)//e
在这里我们就可以看出call函数的意思了:指定一个对象o1去调用其他对象o2的方法,此时this对象指向o1
好了,那为什么前面我们说通常呢?因为,这里的thisArg是可以指定为null和undefined的。请看:
//例子6 var d = { getThis:function(){ console.log(this) } } d.getThis.call(null)//Window d.getThis.call(undefined)//Window
此时的this指向全局对象Window
箭头函数
es6中的箭头函数现在也用的比较频繁,但是有个需要注意的点是:
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
其实出现这种情况的根本原因是:箭头函数没有this对象,所以箭头函数的this就是外层代码的this
//例子7 var f = { getThis:()=>{ console.log(this) } } f.getThis()//Window
这个例子和前面例子2是基本一样的,只是把普通函数改写成箭头函数,但是此时的this对象已经指向了外层的Window。
考虑到这一点可能不好理解,我们再看几个例子:
//例子8 var g = { getThis:function(){ return function(){console.log(this)} } } var h = { getThis:function(){ return ()=> console.log(this) } } g.getThis()()//Window h.getThis()()//h
这个例子里,g的getThis写法就和之前的例子3一样,由于函数在全局环境中运行,所以此时this指向Window;h的getThis使用了箭头函数,所以this指向了外层代码块的this所以,此时this指向的是h。
总结
一般情况下this对象指向调用函数的对象,全局环境中执行函数this对象指向Window
在call和apply函数中this指向指定的对象,如果指定的对为undefined或者null,那么this对象指向Window
在箭头函数中,this对象等同于外层代码块的this。
相关推荐:
The above is the detailed content of This rule and this object usage examples in JavaScript. For more information, please follow other related articles on the PHP Chinese website!