call,apply,bind这三个方法在JavaScript中是用来改变函数调用的this指向。那么改变函数this指向有什么用呢?我们先来看一段代码
var a= {
name:'harden',
fn:function () {
console.log(this.name);
}
}
var b = a.fn;
a.fn();//harden
b();//undefined
调用a.fn方法后得到了harden,但在b方法中我想得到harden,为什么却是undefined呢?原因是方法在执行的时候才能确定this到底指向谁,实际上this指向的是最终调用函数的对象。这里当b执行时,实际是window调用了fn函数,那么fn中的this就指向window。
在开始讲call,apply,bind方法前,一起来总结一下this的指向问题。
总体来说this指向可以概括为一句话:this指向在函数的定义时是不确定的,只有函数执行时才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象。但是这个说法在函数被很多对象包裹的时候并不成立,请看下面例子。
简单来说就是:谁(哪个对象)调用的这个函数,那么这个函数中的this就指向这个对象。
例一
function a(){
var name= "harden";
console.log(this.name); //undefined
console.log(this); //Window
}
a();
因为this最终指向调用他的对象,在上述代码中其实是widow触发的这个方法,那么this就指向window,window中并没有定义a,那么就打印出undefined。
例二:
var a = {
name:'harden',
fn:function() {
console.log(this.name);//harden
console.log(this);//指向a(可以自己跑一下)
}
}
a.fn()
这里的this指向a,因为这里的fn函数是通过a.fn()执行的,那么this自然指向a。
说到这我就有疑问了,如果我用 window.a.fn()执行函数,this不就指向window了吗?然后并不是这样的,请看下一个例子。补充一点:window是js的全局对象。
例三:
var a = {
name:'harden',
b:{
name:'james',
fn:function() {
console.log(this.name);//james
console.log(this);//指向b
}
}
}
a.b.fn()
我们看到最终是a调用的方法,那为什么this会指向b呢?现在总结三句话,来完全理解this的指向问题:
情况一:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window(除去严格模式外)。
情况二:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
情况三:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象,例子3可以证明。
构造函数中的this:
function Fn(){
this.name = "harden";
}
var a = new Fn();
console.log(a.name); //harden
这里的a可以点出name,因为new关键字会改变this的指向。为什么new关键字会改变this呢,我自己有两种看法:
1.在new的过程中会创建一个实例对象,通过apply等方法 通过 Fn.apply({}) 使this指向这个空对象,最后把fn方法中的材料加工完后返回给a。
当this遇到return的时候:
function fn()
{
this.user = 'harden';
return {};
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = 'harden';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = 'harden';
return 1;
}
var a = new fn;
console.log(a.user); //harden
function fn()
{
this.user = 'harden';
return undefined;
}
var a = new fn;
console.log(a.user); //harden
总结一下:如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。还有一点就是返回null,null也是对象,但是因为他的特殊性,返回后this还是指向函数本身的实例。
理解完JavaScript中的指向问题,那么回到正题:
1.call
a = { name: 'harden' }
function b () {
console.log(this.name);
}
b.call(a);//harden
b()//undefined
b.call(a)用字面意思来讲就是:把函数b添加到对象a的环境中,使函数中的this指向对象a。
call与apply不同的地方就是传参不同。
2.apply
a = { name: 'harden' }
function b (data1,data2) {
console.log(data1,data2);
}
b.call(a,'a1','a2');//a1 a2
b.apply(a,['a1','a2']);//a1 a2
3.bind
a = { name: 'harden' }
function b () {
console.log(this.name);
}
b.bind(a);//不会执行函数
var aaa = b.bind(a);
aaa()//harden
bind不会立即调用函数,是把函数返回,bind通常用它来指定回调函数的this。
我理解的 JavaScript 函数式编程,都认为属于函数式编程的范畴,只要他们是以函数作为主要载体的。
给你的代码增加一点点函数式编程的特性,最近我对函数式编程非常感兴趣。这个概念让我着迷:应用数学来增强抽象性和强制纯粹性,以避免副作用,并实现代码的良好可复用性。同时,函数式编程非常复杂。
Async/await以及它底层promises的应用正在猛烈地冲击着JS的世界。在大多数客户端和JS服务端平台的支持下,回调编程已经成为过去的事情。当然,基于回调的编程很丑陋的。
如果你曾经了解或编写过JavaScript,你可能已经注意到定义函数的方法有两种。即便是对编程语言有更多经验的人也很难理解这些差异。在这篇博客的第一部分,我们将深入探讨函数声明和函数表达式之间的差异。
随着软件应用的复杂度不断上升,为了确保应用稳定且易拓展,代码质量就变的越来越重要。不幸的是,包括我在内的几乎每个开发者在职业生涯中都会面对质量很差的代码。这些代码通常有以下特征:
在js开发中,程序代码是从上而下一条线执行的,但有时候我们需要等待一个操作结束后,再进行下一步操作,这个时候就需要用到回调函数。 在js中,函数也是对象,确切地说:函数是用Function()构造函数创建的Function对象。
这篇文章主要介绍ES5中函数的4种调用,在ES5中函数内容的this指向和调用方法有关。以及ES6中函数的调用,使用箭头函数,其中箭头函数的this是和定义时有关和调用无关。
函数的三种定义方法分别是:函数定义语句、函数直接量表达式和Function()构造函数的方法,下面依次介绍这几种方法具体怎么实现,在实际编程中,Function()构造函数很少用到,前两中定义方法使用比较普遍。
微软 称excel就实现面向开发者的功能,也就是说我们不仅可以全新定义的公式,还可以重新定义excel的内置函数,现在Excel自定义函数增加了使用 JavaScript 编写的支持,下面就简单介绍下如何使用js来编写excel自定义函数。
这篇文章主要讲解:js立即执行函数是什么?js使用立即执行函数有什么作用呢?js立即执行函数的写法有哪些?
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!