浅谈js中的this,call,apply
Posted 只会一点前端
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈js中的this,call,apply相关的知识,希望对你有一定的参考价值。
什么是this?
简单点来说javascript中的this总是指向一个对象,至于这个对象是什么,就有很多情况了。
出去with和eval不常用的情况,实际应用中,this的指向大致有这四种分类:
1.作为对象的方法调用
var obj = { name: ‘ydb‘, sayName: function(){ console.log(this.name); } } obj.sayName();
2.作为普通函数调用
var obj = { name: ‘ydb‘, sayName: function(){ console.log(this.name); } } var sayName = obj.sayName; sayName();
这里全局的sayName就是一个普通函数,谁调用this就指向谁(在这里浏览器中指向window),输出undefined
3.构造器调用
class Perople { constructor(name){ this.name = name; } sayName(){ console.log(this.name); } } var person1 = new Perople(‘ydb‘);
4.Function.prototype.call和Function.prototype.apply调用
var obj1 = { name: ‘ydb‘, sayName: function(){ console.log(this.name); } } var obj2 = {name: ‘ydb2‘}; var obj3 = {name: ‘ydb3‘}; obj1.sayName.call(obj2); // ydb2 obj1.sayName.apply(obj3); // ydb3
上面就是this常用的四种方法。
关于this我们总是会遇到this指向不正确的问题,比如:
var getID = document.getElementById; console.log(getID(‘div1‘));
假如我们有一个id属性为div1的dom元素,我们这样子获取,在有些浏览器引擎中是会抛出异常的,因为这个方法里面内部用到了this,它希望的this是docuemnt这个对象,我们现在把getID执行,就把这个函数作为普通函数调用了,其内部的this已经指向window了,所以会抛出异常。
我们使用call或者apply来修复这个this,代码如下:
document.getElementById = (function(func){ return function() { return func.apply(document,arguments); } })(document.getElementById) var getID = document.getElementById; console.log(getID(‘div1‘));
好了,现在我们就修复了this,这里用到了高阶函数,不做额外的扩展。
既然call,apply很常用我们就来说说他们之间的区别:
他们都能改变函数执行this的指向,还可以传入额外的参数,但是他们之间的传参是有区别的,看如下代码:
Function.prototype.bind = function(ctx){ var _that = this; //保存原函数的引用 return function() { return _that.apply(ctx,arguments); } }
看看是不是很简单。还可以根据自己的需求扩展这个bind方法,但是这里是为了演示,最好不要给js的内置对象的属性做修改,避免出现全局的错误,想要好的实现,可以参考vue源码中对数组变化监听的实现。这里也用到了高阶函数,所以说高阶函数是走向高级程序员的必经之路(虽然我是一个小彩笔)。
既然有了改变this指向的方法,那我们可以调用其他对象的方法实现很多功能,举一个例子,假如一个对象满足下面两个条件,那么就可以实现这么一个功能。
1.对象本身要可以存取属性
2.对象的length属性可读写
实现的功能如下:
var obj = { length: 0 } Array.prototype.push.call(obj,‘a‘); Array.prototype.push.call(obj,‘b‘); console.log(obj[0]); console.log(obj[1]); console.log(obj.length);
我们知道数组的push方法是增加一个元素,那么我们这里借用数据的push方法,实现了给对象增加元素。
谢谢看官。
以上是关于浅谈js中的this,call,apply的主要内容,如果未能解决你的问题,请参考以下文章