javascript 函数中的 this 的四种绑定形式

new绑定

【故事】
迪斯(this)组建了自己的家庭,并生下多个孩子(通过构造函数new了许多个对象)

图片 1

执行new操作的时候,将创建一个新的对象,并且将构造函数的this指向所创建的新对象

JavaScript

function foo (a) { this.a = a; } var a1 = new foo (1); var a2 = new foo
(2); var a3 = new foo (3); var a4 = new foo (4); console.log(a1.a); //
输出1 console.log(a2.a); // 输出2 console.log(a3.a); // 输出3
console.log(a4.a); // 输出4

1
2
3
4
5
6
7
8
9
10
11
12
13
function foo (a) {
     this.a = a;
}
var a1  = new foo (1);
var a2  = new foo (2);
var a3  = new foo (3);
var a4  = new foo (4);
console.log(a1.a); // 输出1
console.log(a2.a); // 输出2
console.log(a3.a); // 输出3
console.log(a4.a); // 输出4

 

1 赞 2 收藏
评论

图片 2

总结

如果要判断一个运行中的函数的this绑定,就需要找到这个函数的直接调用位置。找到之后就可以顺序应用下面这四条规则来判断this的绑定对象。

  1. 由new调用?绑定到新创建的对象。
  2. 由call或者apply(或者bind)调用?绑定到指定的对象。
  3. 由上下文对象调用?绑定到那个上下文对象。
  4. 默认:在严格模式下绑定到undefined,否则绑定到全局对象。

1 赞 1 收藏
评论

图片 2

当以对象里的方法的方式调用函数时,它们的this是调用该函数的对象.

this的显式绑定:(call和bind方法)

【故事——线路3】
迪斯(this)穿越来异世界“伽瓦斯克利”(javascript),经过努力的打拼,积累了一定的财富,于是他买下了自己的房子

图片 4

上面我们提到了this的隐式绑定所存在的this绑定丢失的问题,也就是对于 “
fireInGrobal = obj.fire”

fireInGrobal调用和obj.fire调用的结果是不同的因为这个函数赋值的过程无法把fire所绑定的this也传递过去。这个时候,call函数就派上用场了

 

call的基本使用方式: fn.call(object)

fn是你调用的函数,object参数是你希望函数的this所绑定的对象。

fn.call(object)的作用:

1.即刻调用这个函数(fn)

2.调用这个函数的时候函数的this指向object对象

例子:

JavaScript

var obj = { a: 1, // a是定义在对象obj中的属性 fire: function () {
console.log(this.a) } } var a = 2; // a是定义在全局环境中的变量 var
fireInGrobal = obj.fire; fireInGrobal(); // 输出2
fireInGrobal.call(obj); // 输出1

1
2
3
4
5
6
7
8
9
10
11
var obj = {
      a: 1,    // a是定义在对象obj中的属性
      fire: function () {
         console.log(this.a)
      }
}
var a = 2;  // a是定义在全局环境中的变量  
var fireInGrobal = obj.fire;
fireInGrobal();   // 输出2
fireInGrobal.call(obj); // 输出1

原本丢失了与obj绑定的this参数的fireInGrobal再次重新把this绑回到了obj

但是,我们其实不太喜欢这种每次调用都要依赖call的方式,我们更希望:能够一次性
返回一个this被永久绑定到obj的fireInGrobal函数,这样我们就不必每次调用fireInGrobal都要在尾巴上加上call那么麻烦了。

怎么办呢?
聪明的你一定能想到,在fireInGrobal.call(obj)外面包装一个函数不就可以了嘛!

JavaScript

var obj = { a: 1, // a是定义在对象obj中的属性 fire: function () {
console.log(this.a) } } var a = 2; // a是定义在全局环境中的变量 var fn =
obj.fire; var fireInGrobal = function () { fn.call(obj) //硬绑定 }
fireInGrobal(); // 输出1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {
      a: 1,    // a是定义在对象obj中的属性
      fire: function () {
        console.log(this.a)
      }
}
var a = 2;  // a是定义在全局环境中的变量  
var fn = obj.fire;
var fireInGrobal = function () {
    fn.call(obj)   //硬绑定
}
      
fireInGrobal(); // 输出1

如果使用bind的话会更加简单

JavaScript

var fireInGrobal = function () { fn.call(obj) //硬绑定 }

1
2
3
var fireInGrobal = function () {
    fn.call(obj)   //硬绑定
}

可以简化为:

JavaScript

var fireInGrobal = fn.bind(obj);

1
var fireInGrobal = fn.bind(obj);

call和bind的区别是:在绑定this到对象参数的同时:

1.call将立即执行该函数

2.bind不执行函数,只返回一个可供执行的函数

【其他】:至于apply,因为除了使用方法,它和call并没有太大差别,这里不加赘述

在这里,我把显式绑定和隐式绑定下,函数和“包含”函数的对象间的关系比作买房和租房的区别

图片 5

因为this的缘故

在隐式绑定下:函数和只是暂时住在“包含对象“的旅馆里面,可能过几天就又到另一家旅馆住了

在显式绑定下:函数将取得在“包含对象“里的永久居住权,一直都会”住在这里“

This在箭头函数中的应用

箭头函数不使用this的四种标准规则,而是根据外层(函数或者全局)作用域来决定this。

我们来看一下箭头函数的词法作用域:

function foo() { // 返回一个箭头函数 return (a) => { //
this继承自foo() console.log(this.a) }; } var obj1 = { a: 2 }; var obj2 =
{ a: 3 }; var bar = foo.call(obj1); bar.call(obj2); // 2, 不是3!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function foo() {
    // 返回一个箭头函数
    return (a) => {
        // this继承自foo()
        console.log(this.a)
    };
}
 
var obj1 = {
    a: 2
};
 
var obj2 = {
    a: 3
};
 
var bar = foo.call(obj1);
bar.call(obj2); // 2, 不是3!

foo()内部创建的箭头函数会捕获调用时foo()的this。由于foo()的this绑定到obj1,bar(引用箭头函数)的this也会绑定到obj1,箭头函数的绑定无法被修改。(new也不行!)

function add(c, d) {

this的隐式绑定

【故事——线路2】
迪斯(this)穿越来异世界“伽瓦斯克利”(javascript)的时候,刚好身上带了一些钱,于是他找到一个旅馆住宿了下来

图片 6

当函数被一个对象“包含”的时候,我们称函数的this被隐式绑定到这个对象里面了,这时候,通过this可以直接访问所绑定的对象里面的其他属性,比如下面的a属性

JavaScript

var obj = { a: 1, fire: function () { console.log(this.a) } }
obj.fire(); // 输出1

1
2
3
4
5
6
7
var obj = {
     a: 1,
      fire: function () {
           console.log(this.a)
        }
}
obj.fire(); // 输出1

现在我们需要对平常司空见惯的的代码操作做一些更深的思考,首先,下面的这两段代码达到的效果是相同的:

JavaScript

// 我是第一段代码 function fire () { console.log(this.a) } var obj = {
a: 1, fire: fire } obj.fire(); // 输出1 // 我是第二段代码 var obj = { a:
1, fire: function () { console.log(this.a) } } obj.fire(); // 输出1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 我是第一段代码
function fire () {
      console.log(this.a)
}
  
var obj = {
      a: 1,
      fire: fire
  }
obj.fire(); // 输出1
// 我是第二段代码
var obj = {
        a: 1,
        fire: function () {
             console.log(this.a)
         }
}
obj.fire(); // 输出1

fire函数并不会因为它被定义在obj对象的内部和外部而有任何区别,也就是说在上述隐式绑定的两种形式下,fire通过this还是可以访问到obj内的a属性,这告诉我们:

1.  this是动态绑定的,或者说是在代码运行期绑定而不是在书写期

2.  函数于对象的独立性, this的传递丢失问题

(下面的描述可能带有个人的情感倾向而显得不太严谨,但这是因为我希望阅读者尽可能地理解我想表达的意思)

new绑定

在传统面向类的语言中,使用new初始化类的时候会调用类中的构造函数,但是JS中new的机制实际上和面向类和语言完全不同。

使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作:

  • 创建(或者说构造)一个全新的对象
  • 这个新对象会被执行[[Prototype]]连接
  • 这个新对象会绑定到函数调用的this
  • 如果函数没有返回其他对象,那么new表达式中的函数会自动返回这个新对象
    如:

function foo(a){ this.a = a } var bar = new foo(2); console.log(bar.a);
// 2

1
2
3
4
5
6
function foo(a){
    this.a = a
}
 
var bar = new foo(2);
console.log(bar.a); // 2

使用new来调用foo(…)时,我们会构造一个新对象并把它绑定到foo(…)调用中的this上。new是最后一种可以影响函数调用时this绑定行为的方法,我们称之为new绑定。

无论如何,foo的this被设置为它被创建时的上下文(在上面的例子中,就是global对象)。这同样适用于在其他函数中创建的箭头函数:这些箭头函数的this被设置为外层执行上下文。

在一串对象属性链中,this绑定的是最内层的对象

在隐式绑定中,如果函数调用位置是在一串对象属性链中,this绑定的是最内层的对象。如下所示:

JavaScript

var obj = { a: 1, obj2: { a: 2, obj3: { a:3, getA: function () {
console.log(this.a) } } } } obj.obj2.obj3.getA(); // 输出3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {
      a: 1,
      obj2: {
           a: 2,
           obj3: {
                a:3,
                getA: function () {
                    console.log(this.a)  
                 }
           }
       }
}
obj.obj2.obj3.getA();  // 输出3

this的优先级

毫无疑问,默认绑定的优先级是四条规则中最低的,所以我们可以先不考虑它。

隐式绑定和显式绑定哪个优先级更高?我们来测试一下:

function foo(a){ console.log(this.a) } var obj1 = { a: 2, foo: foo } var
obj2 = { a: 3, foo: foo } obj1.foo(); // 2 obj2.foo(); // 3
obj1.foo.call(obj2); // 3 obj2.foo.call(obj1); // 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function foo(a){
    console.log(this.a)
}
 
var obj1 = {
    a: 2,
    foo: foo
}
 
var obj2 = {
    a: 3,
    foo: foo
}
 
obj1.foo(); // 2
obj2.foo(); // 3
 
obj1.foo.call(obj2); // 3
obj2.foo.call(obj1); // 2

可以看到,显式绑定优先级更高,也就是说在判断时应当先考虑是否可以存在显式绑定。

现在我们要搞清楚new绑定隐式绑定的优先级谁高谁低 :

function foo(something){ this.a = something } var obj1 = { foo: foo }
var obj2 = {} obj1.foo(2); console.log(obj1.a); // 2
obj1.foo.call(obj2,3); console.log(obj2.a); // 3 var bar = new
obj1.foo(4) console.log(obj1.a); // 2 console.log(bar.a); // 4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function foo(something){
    this.a = something
}
 
var obj1 = {
    foo: foo
}
 
var obj2 = {}
 
obj1.foo(2);
console.log(obj1.a); // 2
 
obj1.foo.call(obj2,3);
console.log(obj2.a); // 3
 
var bar = new obj1.foo(4)
console.log(obj1.a); // 2
console.log(bar.a); // 4

可以看到new绑定隐式绑定优先级高。但是new绑定显式绑定谁的优先级更高呢?

function foo(something){ this.a = something } var obj1 = {} var bar =
foo.bind(obj1); bar(2); console.log(obj1.a); // 2 var baz = new bar(3);
console.log(obj1.a); // 2 console.log(baz.a); // 3

1
2
3
4
5
6
7
8
9
10
11
12
13
function foo(something){
    this.a = something
}
 
var obj1 = {}
 
var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a); // 2
 
var baz = new bar(3);
console.log(obj1.a); // 2
console.log(baz.a); // 3

可以看到,new绑定修改了硬绑定中的this,所以new绑定的优先级比显式绑定更高。

之所以要在new中使用硬绑定函数,主要目的是预先设置函数的一些参数,这样在使用new进行初始化时就可以只传入其余的参数。bind(…)的功能之一就是可以把除了第一个参数(第一个参数用于绑定this)之外的其他参数都传给下层的函数(这种技术称为“部分应用”,是“柯里化”的一种)。举例来说:

function foo(p1,p2){ this.val = p1 + p2; } //
之所以使用null是因为在本例中我们并不关心硬绑定的this是什么 //
反正使用new时this会被修改 var bar = foo.bind(null,’p1′); var baz = new
bar(‘p2’); baz.val; // p1p2 }

1
2
3
4
5
6
7
8
9
10
11
12
function foo(p1,p2){
    this.val = p1 + p2;
}
 
// 之所以使用null是因为在本例中我们并不关心硬绑定的this是什么
// 反正使用new时this会被修改
var bar = foo.bind(null,’p1′);
 
var baz = new bar(‘p2’);
 
baz.val; // p1p2
}

柯里化:在直觉上,柯里化声称“如果你固定某些参数,你将得到接受余下参数的一个函数”。所以对于有两个变量的函数yx,如果固定了
y = 2,则得到有一个变量的函数 2x

Object.defineProperty(o, ‘sum’, {

this的默认绑定

 

【故事——线路1】如果迪斯(this)直到天黑前都没有找到能收留自己的住所,他眼看就要过上非洲难民的生活,
这时候,一位乐善好施的魔法师村长——window救世主一般地出现了:先住在我家吧!图片 7

【正文】

当一个函数没有明确的调用对象的时候,也就是单纯作为独立函数调用的时候,将对函数的this使用默认绑定:绑定到全局的window对象

JavaScript

function fire () { console.log(this === window) } fire(); // 输出true

1
2
3
4
function fire () {
     console.log(this === window)
}
fire(); // 输出true

上面的例子我相信对大多数人都很简单,但有的时候我们把例子变一下就会具有迷惑性:

JavaScript

function fire () { // 我是被定义在函数内部的函数哦! function
innerFire() { console.log(this === window) } innerFire(); //
独立函数调用 } fire(); // 输出true

1
2
3
4
5
6
7
8
function fire () {
  // 我是被定义在函数内部的函数哦!
     function innerFire() {
  console.log(this === window)
      }
     innerFire(); // 独立函数调用
}
fire(); // 输出true

函数 innerFire在一个外部函数fire里面声明且调用,那么它的this是指向谁呢?
仍然是window

许多人可能会顾虑于fire函数的作用域对innerFire的影响,但我们只要抓住我们的理论武器——没有明确的调用对象的时候,将对函数的this使用默认绑定:绑定到全局的window对象,便可得正确的答案了

下面这个加强版的例子也是同样的输出true

JavaScript

var obj = { fire: function () { function innerFire() { console.log(this
=== window) } innerFire(); // 独立函数调用 } } obj.fire(); //输出 true

1
2
3
4
5
6
7
8
9
var obj = {
   fire: function () {
       function innerFire() {
          console.log(this === window)
        }
        innerFire();   // 独立函数调用
     }
}
obj.fire(); //输出 true

注意】在这个例子中,
obj.fire()的调用实际上使用到了this的隐式绑定,这就是下面我要讲的内容,这个例子我接下来还会继续讲解

【总结】
凡事函数作为独立函数调用,无论它的位置在哪里,它的行为表现,都和直接在全局环境中调用无异

显式绑定

简单的说,就是指定this,如:call、apply、bind、new绑定等

//原始值 7 被隐式转换为对象

javascript 函数中的 this 的四种绑定形式

2017/08/16 · JavaScript
· this

原文出处:
外婆的彭湖湾   

 javascript中的this和函数息息相关,所以今天,我就给大家详细地讲述一番:javascript函数中的this

一谈到this,很多让人晕晕乎乎的抽象概念就跑出来了,这里我就只说最核心的一点——函数中的this总指向调用它的对象,接下来的故事都将围绕这一点展开

 

(提醒前排的筒子们准备好茶水和西瓜,我要开始讲故事啦!!)

【故事】有一个年轻人叫“迪斯”(this),有一天,迪斯不小心穿越到一个叫
“伽瓦斯克利”(javascript)的 异世界,此时此刻迪斯身无分文,
他首先要做的事情就是——找到他的住宿的地方——调用函数的对象图片 8

JavaScript 中的 this 全面解析

2017/05/26 · JavaScript
· this

原文出处: Simon_ITer   

GitHub地址:

this的指向问题应该是让每一个前端er都头疼的问题,我也一样,曾经遇到甚至都是一顿乱猜。最近在研读一些书籍如《你不知道的JavaScript》和《JavaScript语言精粹与编程实践》,让我对this的问题豁然开朗。故写下此篇文章,分享一下我的心得。

}

隐式绑定下,作为对象属性的函数,对于对象来说是独立的

基于this动态绑定的特点,写在对象内部,作为对象属性的函数,对于这个对象来说是独立的。(函数并不被这个外部对象所“完全拥有”)

我想表达的意思是:在上文中,函数虽然被定义在对象的内部中,但它和“在对象外部声明函数,然后在对象内部通过属性名称的方式取得函数的引用”,这两种方式在性质上是等价的而不仅仅是效果上

定义在对象内部的函数只是“恰好可以被这个对象调用”而已,而不是“生来就是为这个对象所调用的”

 

借用下面的隐式绑定中的this传递丢失问题来说明:

JavaScript

var obj = { a: 1, // a是定义在对象obj中的属性 1 fire: function () {
console.log(this.a) } } var a = 2; // a是定义在全局环境中的变量 2 var
fireInGrobal = obj.fire; fireInGrobal(); // 输出 2

1
2
3
4
5
6
7
8
9
10
var obj = {
      a: 1,    // a是定义在对象obj中的属性   1
      fire: function () {
   console.log(this.a)
        }
      }
var a = 2;  // a是定义在全局环境中的变量    2
var fireInGrobal = obj.fire;  
fireInGrobal(); //  输出 2

上面这段简单代码的有趣之处在于: 这个于obj中的fire函数的引用(
fireInGrobal)在调用的时候,行为表现(输出)完全看不出来它就是在obj内部定义的
其原因在于:我们隐式绑定的this丢失了!!
从而 fireInGrobal调用的时候取得的this不是obj,而是window

上面的例子稍微变个形式就会变成一个可能困扰我们的bug:

JavaScript

var a = 2; var obj = { a: 1, // a是定义在对象obj中的属性 fire: function
() { console.log(this.a) } } function otherFire (fn) { fn(); }
otherFire(obj.fire); // 输出2

1
2
3
4
5
6
7
8
9
10
11
var a = 2;
var obj = {
    a: 1,    // a是定义在对象obj中的属性
    fire: function () {
          console.log(this.a)
     }
}  
function otherFire (fn) {
     fn();
}  
otherFire(obj.fire); // 输出2

在上面,我们的关键角色是otherFire函数,它接受一个函数引用作为参数,然后在内部直接调用,但它做的假设是参数fn仍然能够通过this去取得obj内部的a属性,但实际上,
this对obj的绑定早已经丢失了,所以输出的是全局的a的值(2),而不是obj内部的a的值(1)

隐式丢失

一个最常见的this绑定问题就是被隐式绑定的函数会丢失绑定对象,也就是说他回应用默认绑定,从而把this绑定到全局对象或者undefined上,取决于是否是严格模式。

function foo() { console.log( this.a ) } var obj1 = { a: 2, foo: foo }
var bar = obj1.foo; // 函数别名! var a = “oops, global”; //
a是全局对象的属性 bar(); // “oops, global”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function foo() {
    console.log( this.a )
}
 
var obj1 = {
    a: 2,
    foo: foo
}
 
var bar = obj1.foo; // 函数别名!
 
var a = "oops, global"; // a是全局对象的属性
 
bar(); // "oops, global"

虽然bar是obj.foo的一个引用,但是实际上,它引用的是foo函数本身,因此此时的bar()其实是一个不带任何修饰的函数调用,因此应用了默认绑定

一个更微妙、更常见并且更出乎意料的情况发生在传入回调函数时

function foo() { console.log( this.a ) } function doFoo( fn ){ // fn
其实引用的是 foo fn(); //

1
2
3
4
5
6
7
function foo() {
    console.log( this.a )
}
 
function doFoo( fn ){
    // fn 其实引用的是 foo
    fn(); //

参数传递其实就是一种隐式赋值,因此我们传入函数时也会被隐式赋值,所以结果和上一个例子一样,如果把函数传入语言内置的函数而不是传入自己声明的函数(如setTimeout等),结果也是一样的

//在浏览器中:

硬绑定

function foo( something ) { console.log( this.a, something) return
this.a + something } var obj = { a: 2 } var bar = function() { return
foo.apply( obj, arguments) } var b = bar(3); // 2 3 console.log(b); // 5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function foo( something ) {
    console.log( this.a, something)
    return this.a + something
}
 
var obj = {
    a: 2
}
 
var bar = function() {
    return foo.apply( obj, arguments)
}
 
var b = bar(3); // 2 3
console.log(b); // 5

这里简单做一下解释:
在bar函数中,foo使用apply函数绑定了obj,也就是说foo中的this将指向obj,与此同时,使用arguments(不限制传入参数的数量)作为参数传入foo函数中;所以在运行bar(3)的时候,首先输出obj.a也就是2和传入的3,然后foo返回了两者的相加值,所以b的值为5

同样,本例也可以使用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
2
3
4
5
6
7
8
9
10
11
12
13
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

}

隐式绑定

关于this,一般来说,谁调用了方法,该方法的this就指向谁,如:

function foo(){ console.log(this.a) } var a = 3; var obj = { a: 2, foo:
foo }; obj.foo(); //
输出2,因为是obj调用的foo,所以foo的this指向了obj,而obj.a = 2

1
2
3
4
5
6
7
8
9
10
11
12
function foo(){
    console.log(this.a)
}
 
var a = 3;
 
var obj = {
    a: 2,
    foo: foo
};
 
obj.foo(); // 输出2,因为是obj调用的foo,所以foo的this指向了obj,而obj.a = 2

如果存在多次调用,对象属性引用链只有上一层或者说最后一层在调用位置中起作用,如:

function foo() { console.log( this.a ) } var obj2 = { a: 42, foo: foo }
var obj1 = { a: 2, obj2: obj2 } obj1.obj2.foo(); // 42

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function foo() {
    console.log( this.a )
}
 
var obj2 = {
    a: 42,
    foo: foo
}
 
var obj1 = {
    a: 2,
    obj2: obj2
}
 
obj1.obj2.foo(); // 42

}

return x;

//在Node中:

// 作为obj对象的一个方法来调用bar,把它的this绑定到obj。

console.log(o.a); // logs 37

return (this.a + this.b + this.c) / 3;

this.a = 37;

}

console.log(Object.prototype.toString.call(this));

}

在第二个例子中,this的确应该是undefined,因为f2是被直接调用的,而不是作为对象的属性/方法调用的(比如window.f2())。有一些浏览器最初在支持严格模式时没有正确实现这个功能,于是它们错误地返回了window对象。

*

}

在函数内部,this的值取决于函数被调用的方式

// 在浏览器中, window 对象同时也是全局对象:

}

注意:如果将thisArg传递给call、bind、或者apply,它将被忽略(译者注:thisArg即传入三个函数中的第一个参数)。不过你仍然可以为调用添加参数,不过第一个参数应该设置为null。

console.log(o.a); // logs 38

this.b = “MDN”;

// x所指向的匿名函数赋值给fn。

* function MyConstructor(){

这说明this的值只与 函数从o的成员f中调用的方式 有关系。

*/

// 第一个参数是作为‘this’使用的对象

console.log(b) //”MDN”

*  // 如果函数具有返回对象的return语句,则该对象将是 new 表达式的结果。

console.log(o.b.g()); // logs 42

}

*  // 函数实体写在这里

p.a = 1;

无论是否在严格模式下,在全局执行上下文中(在任何函数体外部)this都指代全局对象。

// 第二个参数是一个数组,数组里的元素用作函数调用中的参数

  1. getter 与 setter 中的 this

console.log(g()); // azerty

function bar() {

};

whatsThis.apply(obj); // 通过apply调用 ,返回’Custom’

/*

使用call和apply函数的时候要注意,如果传递的this值不是一个对象,JavaScript将会尝试使用内部ToObject操作将其转换为对象。因此,如果传递的值是一个原始值比如 7
或 ‘foo’ ,那么就会使用相关构造函数将它转换为对象,所以原始值7通过new
Number(7)被转换为对象,而字符串’foo’使用new String(‘foo’)转化为对象,例如:

然而,在严格模式下,this将保持他进入执行上下文时的值,所以下面的this将会默认为undefined。

o.b = {

console.log(foo() === globalObject); // true

  1. call和apply方法

console.log(foo.call(obj) === globalObject); // true

}

return this.prop;

o.f = independent;

var p = Object.create(o);

因为下面的代码不是在严格模式下执行,且this的值不是通过调用设置的,所以this的值默认指向全局对象。

console.log(obj.foo() === globalObject); // true

var globalObject = this;

var o = {

* }

  1. 箭头函数

在绝大多数情况下,函数的调用方式决定了this的值。this不能在执行期间被赋值,并且在每次函数被调用时this的值也可能会不同。ES5引入了bind方法来设置函数的this值,而不用考虑函数如何被调用的,ES2015引入了支持this词法解析的箭头函数(它在闭合的执行上下文内设置this的值)。

console.log(foo() === globalObject); // true

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图