JavaScript之this全面解析已经常见实例
栏目: JavaScript · 发布时间: 6年前
内容简介:this 关键字在 Javascript 中非常常见,但是很多开发者很难说清它到底指向什么。大部分人会从字面意思上去理解 this,认为 this 指向函数自身,实际上总结:函数被调用时发生 this 绑定,this 一共有 4 中绑定规则,接下来一一介绍每种规则的解释和规则直接的优先级
this 关键字在 Javascript 中非常常见,但是很多开发者很难说清它到底指向什么。大部分人会从字面意思上去理解 this,认为 this 指向函数自身,实际上 this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调 用时的各种条件。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
总结:函数被调用时发生 this 绑定, this 指向什么完全取决于函数在哪里被调用 。
一、this 的绑定规则
this 一共有 4 中绑定规则,接下来一一介绍每种规则的解释和规则直接的优先级
- 默认绑定(严格/非严格模式)
- 隐式绑定
- 显式绑定
- new 绑定
1.1 默认绑定(严格/非严格模式)
- 独立函数调用: 独立函数调用时 this 使用默认绑定规则,默认绑定规则下 this 指向 window(全局对象) 。
- 严格模式下: this 无法使用默认绑定,this 会绑定到 undefined。
独立函数调用
function foo() {
console.log(this.a);
}
var a = 2;
foo(); // 2
复制代码
严格模式下:
function foo() {
"use strict";
console.log(this); //undefined
console.log(this.a); //Uncaught TypeError: Cannot read property 'a' of undefined
}
var a = 2;
foo();
复制代码
注意下边两种情况
var age = "18";
var obj = {
name: "heyushuo",
age: 25,
fn: function() {
function sayName() {
console.log(this); //window
console.log(this.age); //undefined
}
sayName();
}
};
obj.fn();
复制代码
函数 sayName 虽然是在 obj.fn 内部定义的,但是它仍然是一个独立函数调用,this 仍然指向 window。
var a = "global";
var obj = {
a: 2,
foo: function() {
console.log(this.a); //global
}
};
var bar = obj.foo; // 函数别名!
bar();
复制代码
虽然 bar 是 obj.foo 的一个引用,但是实际上,它引用的是函数本身,因此此时的 bar() 其实是一个不带任何修饰的独立函数调用,因此应用了默认绑定。
1.2 隐式绑定
当函数引用有上下文对象时(例如:obj.foo 这个时候使用 obj 上下文来引用函数 foo),隐式绑定规则会把函数中的 this 绑定到这个上下文对象。
var obj = {
name: "heyushuo,
foo: function() {
console.log(this.name); //heyushuo
}
};
obj.foo();
复制代码
对象属性引用链中只有上一层或者说最后一层在调用中起作用。
var obj = {
name: "heyushuo",
obj1: {
name: "kebi",
foo: function() {
console.log(this.name); // kebi
}
}
};
obj.obj1.foo();
复制代码
隐式丢失被隐式绑定的函数会丢失绑定对象,而应用默认绑定,把 this 绑定到全局对象或者 undefined(严格模式) 上。 第一种
var a = "global";
var obj = {
a: 2,
foo: function() {
console.log(this.a); //global
}
};
var bar = obj.foo; // 函数别名!
bar();
复制代码
虽然 bar 是 obj.foo 的一个引用,但是实际上,它引用的是函数本身,因此此时的 bar() 其实是一个不带任何修饰的独立函数调用,因此应用了默认绑定。
第二种传入回调函数时:
var a = "global";
var obj = {
a: 2,
foo: function() {
console.log(this.a); //global
}
};
var bar = obj.foo; // 函数别名!
function doFoo(fn) {
fn(); // <-- 调用位置!
}
doFoo(bar); //global
//和下边这种一样
setTimeout(obj.foo, 300);
复制代码
1.3 显示绑定
通过 call() 或者 apply()方法。第一个参数是一个对象,在调用函数时将这个对象绑定到 this 上,称之为显示绑定。
function foo() {
console.log(this.a);
}
var obj = {
a: 2
};
foo.call(obj); // 2
复制代码
显示绑定引申出来一个硬绑定,代码如下
function foo(something) {
console.log( this.a, something );
return this.a + something;
}
// 简单的辅助绑定函数
function bind(fn, obj) {
return function() {
return fn.apply( obj, arguments ); //内部已经强制绑定了传入函数this的指向
};
}
var obj = {
a:2
};
var bar = bind( foo, obj );
var b = bar( 3 ); // 2 3
console.log( b ); // 5
复制代码
bar函数无论如何调用,它总会手动在 obj 上调用 fn,强制把 fn 的 this 绑定到了 obj。这样也解决前面提到的 丢失绑定问题
由于 硬绑定是一种非常常用的模式 ,所以在 ES5 中提供了内置的方法 Function.prototype.bind
function foo(something) {
console.log( this.a, something );
return this.a + something;
}
var obj = {
a:2
};
var bar = foo.bind( obj );
var b = bar( 3 ); // 2 3
console.log( b ); // 5
复制代码
1.4 new绑定
使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。
- 创建(或者说构造)一个全新的对象。
- 这个新对象会被执行 [[ 原型 ]] 连接。
- 这个新对象会绑定到函数调用的 this。
- 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。
例如:
function foo() {
this.name = "heyushuo";
this.age = 25
}
foo.prototype.sayName = function(){
console.log(this.name+this.age);
}
var bar = new foo();
console.log(bar); //{name: "heyushuo", age: 25}
//这个新对象会绑定到函数调用的 this。所以此时的this就是bar对象
console.log( bar.age ); // 25
复制代码
如下图是 new foo() 这个对象
以上所述就是小编给大家介绍的《JavaScript之this全面解析已经常见实例》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Oracle的实例恢复解析
- Tomcat 日志分割实例解析
- SQL Server的实例恢复解析
- python使用锁访问共享变量实例解析
- Python生成器以及应用实例解析
- SQL 联合查询与XML解析实例详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Microsoft.NET框架程序设计
Jeffrey Richter / 李建忠 / 清华大学出版社 / 2003-11 / 68.00元
《Microsoft.NET框架程序设计》(修订版)是《微软.NET程序员系列》丛书之一,主要介绍如何开发面向Microsoft.NET框架的各种应用程序。Microsoft.NET框架是微软公司推出的新平台,包含通用语言运行时(CLR)和.NET框架类库(FCL)。《Microsoft.NET框架程序设计》(修订版)将深入解释CLR的工作机制及其提供的各种构造,同时还将讨论FCL中一些重要的类型......一起来看看 《Microsoft.NET框架程序设计》 这本书的介绍吧!
html转js在线工具
html转js在线工具
RGB CMYK 转换工具
RGB CMYK 互转工具