之前我们说过this是在运行时进行绑定的,并不是在编写时绑定。JavaScript的this总指向一个对象,具体指向哪一个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。
this的指向大致可以分为下面几种:
- 1、作为对象的方法调用,this指向该对象
- 2、作为普通函数,this指向window
- 3、构造器调用,this指向返回的这个对象
- 4、箭头函数,箭头函数的this绑定的是this所在函数定义在哪个对象下,就绑定哪个对象,如果也有嵌套的情况,则this绑定到最近一层对象上
关于箭头函数this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。
作为对象的方法调用
var obj = {
a: 1,
getA: function() {
console.log(this === obj) // true
console.log(this.a) // 1
}
}
obj.getA()
构造器调用
var MyClass = function() {
this.name = 'sven'
}
var myclass = new MyClass()
console.log(myclass.name) // 'sven'
隐式绑定
对象属性引用链中只有上一层或者说最后一层在调用位置中起作用,foo中的this会指向最近一层的obj2
function foo() {
console.log(this.a)
}
var obj2 = {
a: 42,
foo: foo
}
var obj1 = {
a: 42,
obj2: obj2
}
obj1.obj2.foo() // 42
改变this的指向
- 1、使用es6的箭头函数
- 2、在函数内部使用that = this
- 3、使用apply,call,bind
- 4、new实例化一个对象
通过apply和call改变函数的this指向,第一个参数都是要指向的this,如果为null函数体内的this会指向默认宿主对象,在浏览器中则是window。第二个参数,apply是数组或者类数组,而call则是arg1,arg2...这种形式。
如何实现一个call、apply
var foo = {
value: 1
};
function bar() {
console.log(this.value);
}
bar.call(foo); // 1
从上面代码可以看出,call改变了this的指向,指向了foo,bar函数执行了。上面我们提到过作为对象的方法调用,this会指向这个对象,因此也可以拿到这个对象的属性。因此我们可以利用这个原理来实现call:
- 1、将函数设为对象的属性
- 2、执行该函数
- 3、删除该属性
Function.prototype.call = function (context) {
var context = Object(context) || window; // 第一个参数为null指向window
context.fn = this;
var args = [];
for (var i = 1, len = arguments.length; i < len; i++) { // 获取call后面的参数
args.push('arguments[' + i + ']');
}
var result = eval('context.fn(' + args + ')'); // 依次将参数放到方法中执行
delete context.fn
return result;
}
如何实现一个bind
bind 会返回一个函数,并不会立即执行 第二个是带参数(第一个参数要指向的this,后面的的参数用来传递)
Function.prototype.bind2 = function (context) {
var self = this;
// 获取bind2函数从第二个参数到最后一个参数
var args = Array.prototype.slice.call(arguments, 1);
var fbound = function () {
self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
}
return fbound;
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!