总结
- 函数通过this在运行时需要确定其运行环境
- 当做值传递和返回
- 当做对象和构造函数
- 动态绑定、事件监听
- this自然就指向了本节点对象
- 动态绑定的事件本就是为节点对象的属性(事件名称前面加'on')重新赋值为一个匿名函数
- 函数在执行时就是在节点对象的环境下
- 构造函数
- 指向该对象
- 运行后会返回一个对象,该对象的 proto 指向 构造函数 的 prototype
- 定时器
- setInterval(obj.fun,1000); // this指向window对象
- setInterval('obj.fun()',1000); // this指向obj对象
- 箭头函数中的this
- this固定指向当前定义时所在的对象
定义
1:this永远指向一个对象
2:this的指向完全取决于函数调用的位置(谁调用指向谁)
函数中的 this
- 函数通过this在运行时需要确定其运行环境
- 当做值传递和返回
- 当做对象和构造函数
当做值传递和返回
var A = {
name: '张三',
f: function () {
console.log('姓名:' + this.name);
}
};
var B = {
name: '李四'
};
B.f = A.f;
B.f() // 姓名:李四
A.f() // 姓名:张三
A.f属性被赋给B.f = 将A对象将匿名函数的地址赋值给B对象
当做对象和构造函数
function foo() {
console.log(this.a);
}
var obj2 = {
a: 2,
fn: foo
};
var obj1 = {
a: 1,
o1: obj2
};
obj1.o1.fn(); // 2
obj1对象的o1属性值是obj2对象的地址,而obj2对象的fn属性的值是函数foo的地址;函数foo的调用环境是在obj2中的,因此this指向对象obj2。
面向对象
function Foo() {
getName = function () {
console.log(1);
};
return this;
}
Foo.getName = function () {
console.log(2);
};
Foo.prototype.getName = function () {
console.log(3);
};
var getName = function () {
console.log(4);
};
function getName() {
console.log(5);
}
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
// 变量提升:var-提前声明 function-提前声明+定义
// 加括号有参数,不加括号没有参数
// 不是私有变量找上级作用域
// new Foo() 创建实例要找原型
// 2
// 4
// 1
// 1
// 2
// 3
// 3
事件绑定中的this
行内绑定
<input type="button" value="按钮" onclick="clickFun()">
<script>
function clickFun(){
this // 此函数的运行环境在全局window对象下,因此this指向window;
}
</script>
<input type="button" value="按钮" onclick="this">
<!-- 运行环境在节点对象中,因此this指向本节点对象 -->
-
当前运行环境下没有
clickFun函数,浏览器就在整个环境中寻找一个叫clickFun的函数并执行这个函数,所以函数内部的this就指向了全局对象window -
如果不是一个函数调用,直接在当前节点对象环境下使用this,那么显然this就会指向当前节点对象
动态绑定、事件监听
<input type="button" value="按钮" id="btn">
<script>
var btn = document.getElementById('btn');
btn.onclick = function(){
this ; // this指向本节点对象
}
</script>
-
动态绑定的事件本就是为节点对象的属性(事件名称前面加'on')重新赋值为一个匿名函数,this自然就指向了本节点对象
-
事件监听中this指向的原理与动态绑定基本一致
构造函数中的this
function Pro(){
this.x = '1';
this.y = function(){};
}
var p = new Pro();
- 当 JS 引擎指向到第3步的时候,会强制的将this指向新创建出来的这个对象
window定时器中的this
var obj = {
fun:function(){
this ;
}
}
setInterval(obj.fun,1000); // this指向window对象
setInterval('obj.fun()',1000); // this指向obj对象
-
setInterval():window对象下内置的一个方法。第一个参数是一个函数,第二个参数则是执行前面函数或者代码的时间间隔-
setInterval(obj.fun,1000) 将obj.fun的地址当做参数传递给了
setInterval方法,1000毫秒后,函数的运行就已经是在window对象下了,其中的this则指向的全局window对象 -
setInterval('obj.fun()',1000)中传入的一段可执行的 JS 代码;1000毫秒后当 JS 引擎来执行这段代码时,则是通过obj对象来找到fun函数并调用执行,那么函数的运行环境依然在对象obj内,所以函数内部的this也就指向了obj对象
-
-
定时器是window的方法,所以会指向window
箭头函数中的this
-
箭头函数内部并没有绑定this的机制,所以this固定指向当前定义时所在的对象
-
上下文环境不做变化,this为全局对象,即this定义在顶层环境
-
内部的this就是外层代码块的this
var isObject = {
a: 'hhh',
functions: () => {
console.log("对象:",this);
}
}
isObject.functions();
//输出结果:对象:Window {postMessage: , blur: , focus: , close: , parent: Window, …}
- 同样是对象方法,箭头函数里的this指向的是window对象
var isObject = {
a: 'hhh',
functions: () => {
this.a = 0
console.log("结果:",this.a);
}
}
isObject.functions();
//输出结果:结果:0
-
在isObject对象functions方法内部定义了一个属性a,它属于this全局对象,所以输出结果为0。
-
this 不是只能指向window
function myFunction() {
var innerfunction = () => {
console.log('x:', this.x);
}
return innerfunction;
}
var test = myFunction.call({x: 1});
test();
//输出结果:1
-
this此时指向myFunction里的对象{x:1}
-
箭头函数本身并不能绑定this,所以它不能使用apply,call,bind方法来改变上下文环境
引用: