澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站:箭头函数this深刻理解,

2019-06-16 作者:澳门新萄京赌场网址   |   浏览(80)

JavaScript 中 this 的运维机制及爬坑指南

2018/03/14 · JavaScript · this

原稿出处: [Dr. Axel

要依靠this 所在的岗位来明白它,情形概略能够分为3种:

要依照this 所在的岗位来驾驭它,意况大约能够分为3种:

1.含义

先来谈谈ES5中的this
在ES5中,各样函数在被调用时都会自行得到this这些新鲜的对象。由此,各个内部函数不能够访问到表面函数的this对象。(跟变量访问同一,假设某个情况存在有个别变量,就不会去搜索全局处境的同名变量)。

Rauschmayer]()   译文出处:[众成翻译

woolll]()   

澳门新萄京官方网站 1

在 JavaScript 中,this 那些奇怪的变量是争持比较复杂的,因为 this 不唯有用在面向对象意况中,在此外任啥地点方也是可用的。 本篇博文中会解释 this 是什么样行事的以及选择中恐怕导致问题的地点,最终奉上最佳施行。

为了越来越好掌握 this,将 this 使用的光景分成三类:

  • 在函数内部 this 三个额外的,平常是包蕴的参数。
  • 在函数外部(超级功能域中): 那指的是浏览器中的全局对象恐怕Node.js 中叁个模块的输出。
  • 在传递给eval()的字符串中: eval() 只怕取得 this 当前值值,只怕将其安装为全局对象,取决于 this 是一贯调用照旧直接调用。

咱俩来探望每一个连串。

  1、在函数中:this 常常是贰个含有的参数。

  1、在函数中:this 经常是一个分包的参数。

this关键字是贰个百般重要的语法点。首先,this总是回到三个对象,轻松说,就是回到属性或格局“当前”所在的靶子。

** this对象是在运作时根据函数的执行情况调整的。**

this 在函数中

那是最常用的 this 使用办法,函数通过扮演二种不一致的角色来表示 JavaScript 中的全体可调用结构体:

  • 一般性函数(this 在非严谨情势下为全局对象,在严苛方式下为undefined)
  • 构造函数(this 指向新制造的实例)
  • 主意(this 是指方法调用的接收者)

在函数中,this 平时被以为是二个附加的,隐含的参数。

  2、在函数外(一流成效域中):在浏览器中this 指的是全局对象;在Node.js中指的是模块(module)的导出(exports)。

  2、在函数外(顶尖成效域中):在浏览器中this 指的是大局对象;在Node.js中指的是模块(module)的导出(exports)。

this.property // this就意味着property属性当前所在的目的。

实行遭受:
a.全局蒙受
运作在全局上下文(在此外函数体外部),this指向全局对象,并且,无论是或不是是在严厉形式下,this都代表全局对象。在浏览器中,this指向window对象。

this 在平时函数中

在日常函数中,this 的值取决于模式:

  • 非严俊格局: this 是指向全局对象 (在浏览器中为window对象)。
function sloppyFunc() { console.log(this === window); // true }
sloppyFunc();

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6bfd7bd4d414140440-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6bfd7bd4d414140440-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6bfd7bd4d414140440-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6bfd7bd4d414140440-4">
4
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6bfd7bd4d414140440-1" class="crayon-line">
function sloppyFunc() {
</div>
<div id="crayon-5b8f6bfd7bd4d414140440-2" class="crayon-line crayon-striped-line">
    console.log(this === window); // true
</div>
<div id="crayon-5b8f6bfd7bd4d414140440-3" class="crayon-line">
  }
</div>
<div id="crayon-5b8f6bfd7bd4d414140440-4" class="crayon-line crayon-striped-line">
sloppyFunc();
</div>
</div></td>
</tr>
</tbody>
</table>
  • 残暴方式: this 的值为 undefined。
function strictFunc() { 'use strict'; console.log(this ===
undefined); // true } strictFunc();

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6bfd7bd58954780524-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6bfd7bd58954780524-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6bfd7bd58954780524-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6bfd7bd58954780524-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6bfd7bd58954780524-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6bfd7bd58954780524-1" class="crayon-line">
function strictFunc() {
</div>
<div id="crayon-5b8f6bfd7bd58954780524-2" class="crayon-line crayon-striped-line">
   'use strict';
</div>
<div id="crayon-5b8f6bfd7bd58954780524-3" class="crayon-line">
   console.log(this === undefined); // true
</div>
<div id="crayon-5b8f6bfd7bd58954780524-4" class="crayon-line crayon-striped-line">
}
</div>
<div id="crayon-5b8f6bfd7bd58954780524-5" class="crayon-line">
strictFunc();
</div>
</div></td>
</tr>
</tbody>
</table>

也正是说,this 是多个设定了私下认可值(window或undefined)的隐式参数。 可是,能够因而 call() 或 apply() 进行函数调用,并精通钦点this的值:``

function func(arg1, arg2) { console.log(this); // a console.log(arg1); // b console.log(arg2); // c } func.call('a', 'b', 'c'); // (this, arg1, arg2) func.apply('a', ['b', 'c']); // (this, arrayWithArgs)

1
2
3
4
5
6
7
function func(arg1, arg2) {
        console.log(this); // a
        console.log(arg1); // b
        console.log(arg2); // c
    }
func.call('a', 'b', 'c'); // (this, arg1, arg2)
func.apply('a', ['b', 'c']); // (this, arrayWithArgs)

  3、传递到eval()中的字符串:假如eval()是被平昔调用的,this 指的是日前指标;若是eval()是被直接调用的,this 就是指全局对象。

  3、传递到eval()中的字符串:要是eval()是被一贯调用的,this 指的是当前目的;要是eval()是被直接调用的,this 正是指全局对象。

var person = {

console.log(this === window); // true;
b.函数遭逢
在函数内部,this的值取决于函数是何等调用的。

this 在构造函数中

尽管经过new运算符调用函数,则函数将改成构造函数。 该运算符成立一个新的对象,并通过它经过this传递给构造函数:``

var savedThis; function Constr() { savedThis = this; } var inst = new Constr(); console.log(savedThis === inst); // true

1
2
3
4
5
6
var savedThis;
function Constr() {
   savedThis = this;
}
var inst = new Constr();
console.log(savedThis === inst); // true

澳门新萄京官方网站:箭头函数this深刻理解,JavaScript中this关键词的使用技巧。在JavaScript中达成,new运算符差不离如下所示(更标准的完结多少复杂一点):

function newOperator(Constr, arrayWithArgs) { var thisValue = Object.create(Constr.prototype); Constr.apply(thisValue, arrayWithArgs); return thisValue; }

1
2
3
4
5
function newOperator(Constr, arrayWithArgs) {
   var thisValue = Object.create(Constr.prototype);
   Constr.apply(thisValue, arrayWithArgs);
   return thisValue;
}

  对那多少个分类,大家做了对应的测试:
  1、在函数中的this

  对这么些分类,大家做了相应的测试:
  1、在函数中的this

name: '张三',

一向调用,非严苛格局下,this默许指向全局对象。不管调用的函数是在大局函数依旧局地情状。

this 在措施中

在形式中,类似于守旧的面向对象的语言:this指向接受者,方法被调用的靶子。

var obj = { method: function () { console.log(this === obj); // true } } obj.method();

1
2
3
4
5
6
var obj = {
    method: function () {
    console.log(this === obj); // true
}
}
obj.method();

  函数基本能够代表JS中享有可被调用的构造,所以那是也最广大的应用this 的地方,而函数又能被子分为下列二种剧中人物:

  函数基本能够代表JS中颇具可被调用的布局,所以那是也最分布的使用this 的情景,而函数又能被子分为下列二种角色:

describe: function () {

function app() {
console.log(this === window); // true
}
app(); // 全局调用
function foo() {
function bar() {
console.log(this === window); // true
}
bar(); // 局地调用
}
foo();
直接调用,严谨形式下,this暗许指向undefined。不管调用的函数是在大局函数照旧有的处境。

this 在一流功用域中

在浏览器中,顶层功用域是大局效能域,它指向global object(如window):

console.log(this === window); // true

1
console.log(this === window); // true

在Node.js中,常常在模块中实践代码。 因而,一流成效域是八个独竖一帜的模块功用域

// `global` (不是 `window`) 指全局对象: console.log(Math === global.Math); // true // `this` 不指向全局对象: console.log(this !== global); // true // `this` refers to a module’s exports: console.log(this === module.exports); // true

1
2
3
4
5
6
7
// `global` (不是 `window`) 指全局对象:
console.log(Math === global.Math); // true
 
// `this` 不指向全局对象:
console.log(this !== global); // true
// `this` refers to a module’s exports:
console.log(this === module.exports); // true

    实函数
    构造器
    方法

    实函数
    构造器
    方法

return '姓名:' this.name;

'use strict'
function app() {
console.log(this === undefined); // true
}
app();
function foo() {
function bar() {
console.log(this === undefined); // true
}
澳门新萄京官方网站:箭头函数this深刻理解,JavaScript中this关键词的使用技巧。bar();
}
foo();
用作指标调用
当函数以对象的办法被调用时,它的this是调用该函数的靶子,并且是偏离近期的靶子。

this 在 eval() 中

eval() 可以被_直接(通过真正的函数调用)或间接_(通过别的方法)。 详细分解在这里。

假如直接调用evaleval() ,则this指向全局对象:``

(0,eval)('this === window') true

1
2
(0,eval)('this === window')
true

再不,借使直白调用eval() ,则this与eval()的碰着中保持一致。 比方:

// 普通函数 function sloppyFunc() { console.log(eval('this') === window); // true } sloppyFunc(); function strictFunc() { 'use strict'; console.log(eval('this') === undefined); // true } strictFunc(); // 构造器 var savedThis; function Constr() { savedThis = eval('this'); } var inst = new Constr(); console.log(savedThis === inst); // true // 方法 var obj = { method: function () { console.log(eval('this') === obj); // true } } obj.method();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 普通函数
function sloppyFunc() {
    console.log(eval('this') === window); // true
}
sloppyFunc();
 
function strictFunc() {
    'use strict';
    console.log(eval('this') === undefined); // true
}
strictFunc();
 
// 构造器
var savedThis;
function Constr() {
     savedThis = eval('this');
}
var inst = new Constr();
console.log(savedThis === inst); // true
 
// 方法
var obj = {
method: function () {
     console.log(eval('this') === obj); // true
}
}
obj.method();

  1.1  在实函数中的this

  1.1  在实函数中的this

}

var o = {
sayName: function() {
console.log(this === o); // true
}
}
o.sayName();
用作构造函数调用

与this相关的牢笼

有四个你须求明白的与this相关的圈套。请留意,在各类情形下,严加方式更安全,因为this在平凡函数中为undefined,并且会在出现难点时告诫。

  在实函数中,this 的值是在于它所处的上下文的方式。

  在实函数中,this 的值是在乎它所处的上下文的格局。

};

当函数被看作构造函数调用时,this指向刚要被创设的新指标。

陷阱:忘记new操作符

假诺您调用三个构造函数时忘记了new操作符,那么你想不到地将this用在一个平日的函数。this会未有科学的值。 在非严苛情势下,this指向window对象,你将开创全局变量:

function Point(x, y) { this.x = x; this.y = y; } var p = Point(7, 5); // 忘记new! console.log(p === undefined); // true // 创立了全局变量: console.log(x); // 7 console.log(y); // 5

1
2
3
4
5
6
7
8
9
10
function Point(x, y) {
    this.x = x;
    this.y = y;
}
var p = Point(7, 5); // 忘记new!
console.log(p === undefined); // true
 
// 创建了全局变量:
console.log(x); // 7
console.log(y); // 5

侥幸的,在严苛情势下会获得警示(this === undefined):

function Point(x, y) { 'use strict'; this.x = x; this.y = y; } var p = Point(7, 5); // TypeError: Cannot set property 'x' of undefined

1
2
3
4
5
6
7
function Point(x, y) {
    'use strict';
    this.x = x;
    this.y = y;
}
var p = Point(7, 5);
// TypeError: Cannot set property 'x' of undefined

  Sloppy方式:this 指的是大局对象(在浏览器中就是window)。

  Sloppy情势:this 指的是全局对象(在浏览器中正是window)。

 

function Person() {
this.name = 'noshower';
}
var person = new Person();
console.log(person.name); //'noshower'
行使call和apply调用,改换函数内部this的绑定值。

陷阱:不科学地领取情势

若果获得形式的值(不是调用它),则能够将该方式转变为函数。 调用该值将产生函数调用,而不是格局调用。 当将艺术作为函数或措施调用的参数字传送递时,大概会产生这种提取。 实际例子包蕴setTimeout()和事件注册管理程序。 作者将利用函数callItt() 来模拟此用例:

/**类似setTimeout() 和 setImmediate() */ function callIt(func) { func(); }

1
2
3
4
/**类似setTimeout() 和 setImmediate() */
function callIt(func) {
      func();
}

若是在非严谨形式下把三个格局作为函数来调用,那么this将针对全局对象并成立全局变量:

var counter = { count: 0, // Sloppy-mode method inc: function () { this.count ; } } callIt(counter.inc); // Didn’t work: console.log(counter.count); // 0 // Instead, a global variable has been created // (NaN is result of applying to undefined): console.log(count); // NaN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var counter = {
    count: 0,
// Sloppy-mode method
inc: function () {
          this.count ;
    }
  }
 
callIt(counter.inc);
 
// Didn’t work:
console.log(counter.count); // 0
 
// Instead, a global variable has been created
// (NaN is result of applying to undefined):
console.log(count);  // NaN

若果在严苛形式下把一个办法作为函数来调用,this为undefined。 同期会获得三个警告:

var counter = { count: 0, // Strict-mode method inc: function () { 'use strict'; this.count ; } } callIt(counter.inc); // TypeError: Cannot read property 'count' of undefined console.log(counter.count);

1
2
3
4
5
6
7
8
9
10
11
12
13
var counter = {
        count: 0,
        // Strict-mode method
        inc: function () {
            'use strict';
            this.count ;
        }
    }
 
callIt(counter.inc);
 
// TypeError: Cannot read property 'count' of undefined
console.log(counter.count);

订正方法是接纳[bind()](http://speakingjs.com/es5/ch17.html#Function.prototype.bind): The fix is to use bind():

var counter = { count: 0, inc: function () { this.count ; } } callIt(counter.inc.bind(counter)); // 成功了! console.log(counter.count); // 1

1
2
3
4
5
6
7
8
9
10
11
var counter = {
    count: 0,
    inc: function () {
          this.count ;
        }
    }
 
callIt(counter.inc.bind(counter));
 
// 成功了!
console.log(counter.count); // 1

bind()创造了多个新的函数,它总是接收一个针对性counter的this。

复制代码 代码如下:

复制代码 代码如下:

person.describe()

function foo() {
console.log(this.name); //'noshower'
}
var obj = {
name: 'noshower'
}
foo.call(obj);
// 函数foo内部的this对象被绑定到了obj对象上。

陷阱:shadowing this

当在叁个办法中应用普通函数时,很轻便忘记前者具有其和好this(固然其无需this)。 由此,你不能够在此在此在此之前端引用该方法的this,因为该this会被屏蔽。 让我们看看出现难题的例证:

var obj = { name: 'Jane', friends: [ 'Tarzan', 'Cheeta' ], loop: function () { 'use strict'; this.friends.forEach( function (friend) { console.log(this.name ' knows ' friend); } ); } }; obj.loop(); // TypeError: Cannot read property 'name' of undefined

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {
        name: 'Jane',
        friends: [ 'Tarzan', 'Cheeta' ],
        loop: function () {
            'use strict';
            this.friends.forEach(
                function (friend) {
                    console.log(this.name ' knows ' friend);
                }
            );
        }
    };
obj.loop();
// TypeError: Cannot read property 'name' of undefined

在日前的事例中,获取this.name退步,因为函数的this个是undefined,它与办法loop()的比不上。 有三种情势能够改良this。

修正1: that = this。 将它分配给三个未有被屏蔽的变量(另一个流行名称是self)并应用该变量。

loop: function () { 'use strict'; var that = this; this.friends.forEach(function (friend) { console.log(that.name ' knows ' friend); }); }

1
2
3
4
5
6
7
loop: function () {
        'use strict';
        var that = this;
        this.friends.forEach(function (friend) {
            console.log(that.name ' knows ' friend);
        });
    }

修正2: bind()。 使用bind()来创立一个this总是指向准确值的函数(在底下的事例中该措施的this)。

loop: function () { 'use strict'; this.friends.forEach(function (friend) { console.log(this.name ' knows ' friend); }.bind(this)); }

1
2
3
4
5
6
loop: function () {
     'use strict';
      this.friends.forEach(function (friend) {
          console.log(this.name ' knows ' friend);
    }.bind(this));
}

修正3: forEach的第二个参数。 此方法具备第贰个参数,this值将作为此值传递给回调函数。

loop: function () { 'use strict'; this.friends.forEach(function (friend) { console.log(this.name ' knows ' friend); }, this); }

1
2
3
4
5
6
loop: function () {
     'use strict';
     this.friends.forEach(function (friend) {
      console.log(this.name ' knows ' friend);
     }, this);
}

function sloppyFunc() {
    console.log(this === window); // true
}
sloppyFunc();

function sloppyFunc() {
    console.log(this === window); // true
}
sloppyFunc();

// "姓名:张三"

行使bind方法,会永恒把this与几个对象绑定。无论这么些函数如何被调用,都更动不了this。

超级奉行

从概念上讲,笔者感觉普通函数没有它自个儿的this,并且想到上述修复是为着保全这种主张。 ECMAScript 6透过[箭头函数](http://2ality.com/二零一三/04/arrow-functions.html)扶助这种艺术 – 未有它们本身的this。 在这么的函数里面,你能够随意使用this,因为不会被挡住:

loop: function () { 'use strict'; // The parameter of forEach() is an arrow function this.friends.forEach(friend => { // `this` is loop’s `this` console.log(this.name ' knows ' friend); }); }

1
2
3
4
5
6
7
8
loop: function () {
    'use strict';
     // The parameter of forEach() is an arrow function
    this.friends.forEach(friend => {
     // `this` is loop’s `this`
     console.log(this.name ' knows ' friend);
     });
}

本人不欣赏使用this作为常常函数的增大参数的API:

beforeEach(function () { this.addMatchers({ toBeInRange: function (start, end) { ... } }); });

1
2
3
4
5
6
7
beforeEach(function () {  
   this.addMatchers({  
   toBeInRange: function (start, end) {  
    ...
    }  
   });  
});

将如此的蕴含参数形成令人注指标参数使得业务更加的扎眼,并且与箭头函数包容。

beforeEach(api => { api.addMatchers({ toBeInRange(start, end) { ... } }); });

1
2
3
4
5
6
7
beforeEach(api => {
   api.addMatchers({
    toBeInRange(start, end) {
       ...
     }
  });
});

JavaScript 浏览器 HTTP HTML ECMAScript 6


1 赞 2 收藏 评论

澳门新萄京官方网站 2

Strict模式:this 的值是undefined。

Strict模式:this 的值是undefined。

上面代码中,this.name表示describe方法所在的此时此刻目的的name属性。调用person.describe方法时,describe方法所在的方今目的是person,所以就是调用person.name。

function foo() {
console.log(this.name); // 'noshower'
}
var obj1 = {
name: 'noshower'
}
var obj2 = {
name: 'DaLin'
}
var a = foo.bind(obj1); //用bind方法,将this举办永远绑定。
a.call(obj2); // 此时选取call方法将改成不了this的针对。
上面大家初叶讲ES6箭头函数中的this对象
箭头函数被调用的时候,不会自动绑定三个this对象。换句话说,箭头函数根本就从未有过和睦的this。它的this都以捕获自其所在上下文的this值。

复制代码 代码如下:

复制代码 代码如下:

由于目的的性质能够赋给另一个指标,所以属性所在的眼下目的是可变的,即this的针对性是可变的。

作为佚名函数被调用。

function strictFunc() {
    'use strict';
    console.log(this === undefined); // true
}
strictFunc();

function strictFunc() {
    'use strict';
    console.log(this === undefined); // true
}
strictFunc();

var A = {

function foo() {
console.log(this); //{name:'noshower'}
setTimeout(() => {
console.log('name:', this.name); //noshower
}, 100);
}
var name = 'DaLin';
foo.call({ name: 'noshower' });
地点代码中,大家用call()方法,将函数foo的this对象绑定到了指标{name:'noshower'}上。由于,箭头函数未有this变量,所以,箭头函数能够访问到外部景况的this变量。此时,箭头函数内部,访问到的是foo函数的this对象。由此,this.name的值是'noshower'。

this 是函数的含有参数,所以它的值总是同样的。可是你是能够透过利用call()可能apply()的方法彰显地定义好this的值的。

this 是函数的含有参数,所以它的值总是同样的。可是你是能够经过应用call()也许apply()的章程呈现地定义好this的值的。

name: '张三',

作为艺术被调用

复制代码 代码如下:

复制代码 代码如下:

describe: function () {

var obj = {
name: 'noshower',
sayName: () => this.name
}
var name = 'bar';
console.log(obj.sayName());
地点代码中,箭头函数是作为指标的章程。因为,箭头函数本人是不绑定this对象的。因而,它只好从表面搬运this对象。下面代码中,唯有全局遭逢存在this对象,因而回到的是window.name,即'bar'。

function func(arg1, arg2) {
    console.log(this); // 1
    console.log(arg1); // 2
    console.log(arg2); // 3
}
func.call(1, 2, 3); // (this, arg1, arg2)
func.apply(1, [2, 3]); // (this, arrayWithArgs)

function func(arg1, arg2) {
    console.log(this); // 1
    console.log(arg1); // 2
    console.log(arg2); // 3
}
func.call(1, 2, 3); // (this, arg1, arg2)
func.apply(1, [2, 3]); // (this, arrayWithArgs)

return '姓名:' this.name;

在章程内部被调用

1.2  构造器中的this

1.2  构造器中的this

}

var obj = {
name: 'noshower',
sayName: function() {
var a = () => this.name;
console.log(a()); // noshower
}
}
var name = 'bar';
obj.sayName();
上面代码中,箭头函数是在sayName方法中运作的。此时,箭头函数的this对象,搬运的是sayName方法的this对象。当sayName函数作为艺术调用时,它的this对象指向obj对象。由此,箭头函数的this.name正是obj.name,即'noshower';

  你能够通过new 将两个函数当做贰个构造器来使用。new 操作成立了四个新的对象,并将这几个目的通过this 传入构造器中。

  你可以透过new 将八个函数当做二个布局器来使用。new 操作成立了三个新的对象,并将以此指标通过this 传入构造器中。

};

采用new 操作符调用,会抛出荒唐

复制代码 代码如下:

复制代码 代码如下:

 

var Obj = (name) => {
this.name = name;
}
new Obj('noshower');
下面的代码,箭头函数作为构造函数被调用,会报错。原因是,箭头函数未有和煦的this对象,就无可如何给this加多属性。

var savedThis;
function Constr() {
    savedThis = this;
}
var inst = new Constr();
console.log(savedThis === inst); // true

var savedThis;
function Constr() {
    savedThis = this;
}
var inst = new Constr();
console.log(savedThis === inst); // true

var B = {

使用call和apply,bind()调用

JS中new 操作的达成原理差不多如上面包车型大巴代码所示(更加准确的贯彻请看这里,这一个完成也相比复杂一些):

JS中new 操作的贯彻原理大概如上面包车型客车代码所示(更加准确的落实请看这里,这一个实现也相比较复杂一些):

name: '李四'

var o = (val) => {
console.log(this.name, val); // bar,bar
};
var obj = {
name: 'foo'
}
var name = 'bar';
o.call(obj, name);
地点代码中,箭头函数使用了call方法来调用。原来想将函数的this绑定在obj对象方面。结果呈现,this被绑定在了全局对象上了。那是因为,箭头函数未有和谐的this对象,此时应用call方法唯有起到了传递参数的功力,未有改变它的this对象。它的this对象依旧来自外部实践情状。

复制代码 代码如下:

复制代码 代码如下:

};

总计一下
箭头函数未有团结的this对象,它总是搬运外部遭遇的this对象。因而,只要离它方今的外部境况中的this改动,箭头函数中的this就改换。如若离它近些日子的条件中的this,未有改换。那么箭头函数中的this就不会改动。

function newOperator(Constr, arrayWithArgs) {
    var thisValue = Object.create(Constr.prototype);
    Constr.apply(thisValue, arrayWithArgs);
    return thisValue;
}

function newOperator(Constr, arrayWithArgs) {
    var thisValue = Object.create(Constr.prototype);
    Constr.apply(thisValue, arrayWithArgs);
    return thisValue;
}

 

箭头函数里的this是概念时所在的功能域,而不是运作时所在的作用域

1.3  方法中的this

1.3  方法中的this

B.describe = A.describe;

  在格局中this 的用法更赞成于古板的面向对象语言:this 指向的接收方,也正是包括有这几个主意的指标。

  在情势中this 的用法更赞成于古板的面向对象语言:this 指向的接收方,也正是包括有这么些法子的目的。

B.describe()

复制代码 代码如下:

复制代码 代码如下:

// "姓名:李四"

var obj = {
    method: function () {
        console.log(this === obj); // true
    }
}
obj.method();

var obj = {
    method: function () {
        console.log(this === obj); // true
    }
}
obj.method();

上面代码中,A.describe属性被赋给B,于是B.describe就象征describe方法所在的这段时间指标是B,所以this.name就针对B.name

2、效用域中的this

2、成效域中的this

function f() {

  在浏览器中,作用域正是大局作用域,this 指的就是以此全局对象(就好像window):

  在浏览器中,功用域就是全局功能域,this 指的就是这一个全局对象(就像window):

return '姓名:' this.name;

复制代码 代码如下:

复制代码 代码如下:

}

<script>
    console.log(this === window); // true
</script>

<script>
    console.log(this === window); // true
</script>

 

在Node.js中,你平凡都是在module中试行函数的。由此,一流功效域是个很非常的模块成效域(module scope):

在Node.js中,你习认为常都以在module中实践函数的。因而,拔尖功能域是个十分特殊的模块作用域(module scope):

var A = {

复制代码 代码如下:

复制代码 代码如下:

name: '张三',

// `global` (not `window`) refers to global object:
console.log(Math === global.Math); // true

// `global` (not `window`) refers to global object:
console.log(Math === global.Math); // true

describe: f

// `this` doesn't refer to the global object:
console.log(this !== global); // true
// `this` refers to a module's exports:
console.log(this === module.exports); // true

// `this` doesn't refer to the global object:
console.log(this !== global); // true
// `this` refers to a module's exports:
console.log(this === module.exports); // true

};

3、eval()中的this

3、eval()中的this

 

  eval()能够被直接(通过调用那一个函数名'eval')恐怕直接(通过别的办法调用,举个例子call())地调用。要打听更加多细节,请看这里。

  eval()能够被一贯(通过调用那么些函数名'eval')或许间接(通过其余方法调用,比方call())地调用。要询问越来越多细节,请看这里。

var B = {

复制代码 代码如下:

复制代码 代码如下:

name: '李四',

// Real functions
function sloppyFunc() {
    console.log(eval('this') === window); // true
}
sloppyFunc();

// Real functions
function sloppyFunc() {
    console.log(eval('this') === window); // true
}
sloppyFunc();

describe: f

function strictFunc() {
    'use strict';
    console.log(eval('this') === undefined); // true
}
strictFunc();

function strictFunc() {
    'use strict';
    console.log(eval('this') === undefined); // true
}
strictFunc();

};

// Constructors
var savedThis;
function Constr() {
    savedThis = eval('this');
}
var inst = new Constr();
console.log(savedThis === inst); // true

// Constructors
var savedThis;
function Constr() {
    savedThis = eval('this');
}
var inst = new Constr();
console.log(savedThis === inst); // true

 

// Methods
var obj = {
    method: function () {
        console.log(eval('this') === obj); // true
    }
}
obj.method();

// Methods
var obj = {
    method: function () {
        console.log(eval('this') === obj); // true
    }
}
obj.method();

A.describe() // "姓名:张三"

 4、与this有关的圈套

 4、与this有关的陷阱

B.describe() // "姓名:李四"

  你要小心下边将介绍的3个和this 有关的骗局。要留心,在下边包车型的士例子中,使用Strict格局(strict mode)都能增进代码的安全性。由于在实函数中,this 的值是undefined,当出现难题的时候,你会拿走警示。

  你要小心上面将介绍的3个和this 有关的牢笼。要小心,在下边包车型客车例证中,使用Strict方式(strict mode)都能增高代码的安全性。由于在实函数中,this 的值是undefined,当出现难点的时候,你会获得警示。

上边代码中,函数f内部选取了this关键字,随着f所在的指标差别,this的针对性也不及。

  4.1  忘记行使new

  4.1  忘记行使new

只要函数被赋给另三个变量,this的针对性就能变。

  若是你不是接纳new来调用构造器,那其实您正是在选拔叁个实函数。由此this就不会是你预期的值。在Sloppy方式中,this 指向的正是window 而你将会创制全局变量:

  假设你不是运用new来调用构造器,那其实您正是在选用二个实函数。因而this就不会是你预期的值。在Sloppy形式中,this 指向的正是window 而你将会创设全局变量:

var A = {

复制代码 代码如下:

复制代码 代码如下:

name: '张三',

function Point(x, y) {
    this.x = x;
    this.y = y;
}
var p = Point(7, 5); // we forgot new!
console.log(p === undefined); // true

function Point(x, y) {
    this.x = x;
    this.y = y;
}
var p = Point(7, 5); // we forgot new!
console.log(p === undefined); // true

describe: function () {

// Global variables have been created:
console.log(x); // 7
console.log(y); // 5

// Global variables have been created:
console.log(x); // 7
console.log(y); // 5

return '姓名:' this.name;

不过假使运用的是strict情势,那您要么会获取警示(this===undefined):

但是假如利用的是strict形式,那您要么会获得警示(this===undefined):

}

复制代码 代码如下:

复制代码 代码如下:

};

function Point(x, y) {
    'use strict';
    this.x = x;
    this.y = y;
}
var p = Point(7, 5);
// TypeError: Cannot set property 'x' of undefined

function Point(x, y) {
    'use strict';
    this.x = x;
    this.y = y;
}
var p = Point(7, 5);
// TypeError: Cannot set property 'x' of undefined

 

4.2 不恰本地接纳方法

4.2 不恰本地应用方法

var name = '李四';

  假让你间接获取贰个主意的值(不是调用它),你便是把这一个主意当做函数在用。当你要将一个艺术当做八个参数字传送入叁个函数也许二个调用方法中,你十分的大概会那样做。set提姆eout()和注册事件句柄(event handlers)正是这种景观。小编将会接纳callIt()方法来效仿那几个现象:

  假使您一直拿走三个措施的值(不是调用它),你便是把这么些法子当做函数在用。当您要将三个情势当做贰个参数字传送入贰个函数可能四个调用方法中,你很恐怕会这么做。setTimeout()和挂号事件句柄(event handlers)便是这种情景。我将会选用callIt()方法来模拟这些情景:

var f = A.describe;

复制代码 代码如下:

复制代码 代码如下:

f() // "姓名:李四"

/** Similar to setTimeout() and setImmediate() */
function callIt(func) {
    func();
}

/** Similar to setTimeout() and setImmediate() */
function callIt(func) {
    func();
}

地点代码中,A.describe被赋值给变量f,内部的this就能够指向f运营时所在的对象(本例是顶层对象)。

假若您是在Sloppy格局下将贰个艺术当做函数来调用,*this*本着的就是大局对象,所以事后创造的都会是全局的变量。

如果您是在Sloppy情势下将多个方式当做函数来调用,*this*针对的就是大局对象,所以随后成立的都会是大局的变量。

能够临近地感觉,this是所有函数运维时的一个潜藏参数,指向函数的运作意况。

复制代码 代码如下:

复制代码 代码如下:

 

var counter = {
    count: 0,
    // Sloppy-mode method
    inc: function () {
        this.count ;
    }
}
callIt(counter.inc);

var counter = {
    count: 0,
    // Sloppy-mode method
    inc: function () {
        this.count ;
    }
}
callIt(counter.inc);

 

// Didn't work:
console.log(counter.count); // 0

// Didn't work:
console.log(counter.count); // 0

 

// Instead, a global variable has been created
// (NaN is result of applying to undefined):
console.log(count);  // NaN

// Instead, a global variable has been created
// (NaN is result of applying to undefined):
console.log(count);  // NaN

2.运用地方

倘诺您是在Strict方式下如此做的话,this是undefined的,你照旧得不到想要的结果,但是至少你会收获一句警告:

只要您是在Strict形式下那样做的话,this是undefined的,你要么得不到想要的结果,可是至少你会赢得一句警告:

1)全局情状

复制代码 代码如下:

复制代码 代码如下:

在全局碰到使用this,它指的正是顶层对象window。

var counter = {
    count: 0,
    // Strict-mode method
    inc: function () {
        'use strict';
        this.count ;
    }
}
callIt(counter.inc);

var counter = {
    count: 0,
    // Strict-mode method
    inc: function () {
        'use strict';
        this.count ;
    }
}
callIt(counter.inc);

this === window // true

// TypeError: Cannot read property 'count' of undefined
console.log(counter.count);

// TypeError: Cannot read property 'count' of undefined
console.log(counter.count);

function f() {

要想获得预期的结果,能够选择bind():

要想赢得预期的结果,能够利用bind():

console.log(this === window); // true

复制代码 代码如下:

复制代码 代码如下:

}

var counter = {
    count: 0,
    inc: function () {
        this.count ;
    }
}
callIt(counter.inc.bind(counter));
// It worked!
console.log(counter.count); // 1

var counter = {
    count: 0,
    inc: function () {
        this.count ;
    }
}
callIt(counter.inc.bind(counter));
// It worked!
console.log(counter.count); // 1

2)构造函数

bind()再创办了三个总是能将this的值设置为counter 的函数。

bind()更创办了一个连接能将this的值设置为counter 的函数。

构造函数中的this,指的是实例对象。

  4.3 隐藏this

  4.3 隐藏this

var Obj = function (p) {

  当您在措施中动用函数的时候,平时会忽视了函数是有本人的this 的。那些this 又分别方法,由此你不能够把这三个this 混在共同行使。具体的请看上面这段代码:

  当您在章程中动用函数的时候,平日会忽视了函数是有温馨的this 的。那个this 又分别方法,因而你不能够把那八个this 混在联合具名行使。具体的请看下边这段代码:

this.p = p;

复制代码 代码如下:

复制代码 代码如下:

};

var obj = {
    name: 'Jane',
    friends: [ 'Tarzan', 'Cheeta' ],
    loop: function () {
        'use strict';
        this.friends.forEach(
            function (friend) {
                console.log(this.name ' knows ' friend);
            }
        );
    }
};
obj.loop();
// TypeError: Cannot read property 'name' of undefined

var obj = {
    name: 'Jane',
    friends: [ 'Tarzan', 'Cheeta' ],
    loop: function () {
        'use strict';
        this.friends.forEach(
            function (friend) {
                console.log(this.name ' knows ' friend);
            }
        );
    }
};
obj.loop();
// TypeError: Cannot read property 'name' of undefined

Obj.prototype.m = function() {

地点的例子里函数中的this.name 不可能利用,因为函数的this 的值是undefined,那和章程loop()中的this 差异。上边提供了二种思路来消除这几个标题:

下面的例证里函数中的this.name 不能够利用,因为函数的this 的值是undefined,那和艺术loop()中的this 分裂样。上面提供了两种思路来缓慢解决那几个难点:

return this.p;

  1、that=this,将this 赋值到叁个变量上,那样就把this 显性地显现出来了(除了that,self 也是个很常见的用于存放this的变量名),之后就应用极其变量:

  1、that=this,将this 赋值到三个变量上,那样就把this 显性地呈现出来了(除了that,self 也是个很广阔的用来存放this的变量名),之后就利用十一分变量:

};

复制代码 代码如下:

复制代码 代码如下:

地点代码定义了贰个协会函数Obj。由于this指向实例对象,所以在构造函数内部定义this.p,就一定于概念实例对象有一个p属性;然后m方法能够重回那几个p属性。

loop: function () {
    'use strict';
    var that = this;
    this.friends.forEach(function (friend) {
        console.log(that.name ' knows ' friend);
    });
}

loop: function () {
    'use strict';
    var that = this;
    this.friends.forEach(function (friend) {
        console.log(that.name ' knows ' friend);
    });
}

var o = new Obj('Hello World!');

2、bind()。使用bind()来创建八个函数,这些函数的this 总是存有你想要传递的值(上面那些例子中,方法的this):

2、bind()。使用bind()来制造三个函数,这一个函数的this 总是存有你想要传递的值(下边那一个例子中,方法的this):

o.p // "Hello World!"

复制代码 代码如下:

复制代码 代码如下:

o.m() // "Hello World!"

loop: function () {
    'use strict';
    this.friends.forEach(function (friend) {
        console.log(this.name ' knows ' friend);
    }.bind(this));
}

loop: function () {
    'use strict';
    this.friends.forEach(function (friend) {
        console.log(this.name ' knows ' friend);
    }.bind(this));
}

3)对象的格局

3、用forEach的第一个参数。forEach的第二个参数会被传播回调函数中,作为回调函数的this 来使用。

3、用forEach的第叁个参数。forEach的第贰个参数会被传播回调函数中,作为回调函数的this 来使用。

当 A 对象的办法被授予 B 对象,该措施中的this就从指向 A 对象变成了指向 B 对象。所以要特意小心,将有些对象的秘诀赋值给另三个对象,会改动this的对准。

复制代码 代码如下:

复制代码 代码如下:

var obj ={

loop: function () {
    'use strict';
    this.friends.forEach(function (friend) {
        console.log(this.name ' knows ' friend);
    }, this);
}

loop: function () {
    'use strict';
    this.friends.forEach(function (friend) {
        console.log(this.name ' knows ' friend);
    }, this);
}

foo: function () {

5、最好实行

5、最好实行

console.log(this);

答辩上,笔者认为实函数并不曾属于自个儿的this,而上述的减轻方案也是比照那个思索的。ECMAScript 6是用箭头函数(arrow function)来促成那么些效果的,箭头函数正是从未协和的this 的函数。在如此的函数中你能够不管选用this,也不用担忧有未有隐式的留存。

力排众议上,小编以为实函数并不曾属于自身的this,而上述的缓和方案也是比照那个思量的。ECMAScript 6是用箭头函数(arrow function)来兑现那么些职能的,箭头函数正是从未和谐的this 的函数。在如此的函数中你能够不管选取this,也不用怀想有未有隐式的留存。

}

复制代码 代码如下:

复制代码 代码如下:

};

loop: function () {
    'use strict';
    // The parameter of forEach() is an arrow function
    this.friends.forEach(friend => {
        // `this` is loop's `this`
        console.log(this.name ' knows ' friend);
    });
}

loop: function () {
    'use strict';
    // The parameter of forEach() is an arrow function
    this.friends.forEach(friend => {
        // `this` is loop's `this`
        console.log(this.name ' knows ' friend);
    });
}

obj.foo() // obj

自身不欣赏有些API把this 当坚实函数的三个增大参数:

自家不爱好有个别API把this 当加强函数的两个叠合参数:

地点代码中,obj.foo方法施行时,它在那之中的this指向obj。

复制代码 代码如下:

复制代码 代码如下:

而是,只有这一种用法(直接在obj对象上调用foo方法),this指向obj;别的用法时,this都对准代码块当前随地对象(浏览器为window对象)。

beforeEach(function () { 
    this.addMatchers({ 
        toBeInRange: function (start, end) { 
            ...
        } 
    }); 
});

beforeEach(function () { 
    this.addMatchers({ 
        toBeInRange: function (start, end) { 
            ...
        } 
    }); 
});

// 情况一

把一个隐性参数写成显性地标准传入,代码会显得越来越好精通,而且这么和箭头函数的须要也很均等:

把一个隐性参数写成显性地标准传入,代码会显得更加好掌握,而且这么和箭头函数的渴求也很均等:

(obj.foo = obj.foo)() // window

复制代码 代码如下:

复制代码 代码如下:

 

beforeEach(api => {
    api.addMatchers({
        toBeInRange(start, end) {
            ...
        }
    });
});

beforeEach(api => {
    api.addMatchers({
        toBeInRange(start, end) {
            ...
        }
    });
});

// 情况二

所在的任务来精晓它,情形大约能够分为3种: 1、在函数中:this 平常是二个含有的参数。 2、在函数外(拔尖功能域中):在浏...

你或然感兴趣的文章:

  • JAVASC智跑IPT THIS详解 面向对象
  • javascript中的this详解
  • Javascript中this的用法详解
  • Javascript学习笔记之 函数篇(二) : this 的办事机制
  • javascript中的self和this用法小结
  • javascript面向对象之访问对象属性的三种方法剖判
  • javascript面向对象之对象的深刻驾驭
  • javascript面向对象急迅入门实例
  • 浅谈JavaScript完成面向对象中的类
  • javascript 面向对象封装与持续
  • javascript面向对象之this关键词用法深入分析

(false || obj.foo)() // window

 

// 情况三

(1, obj.foo)() // window

地点代码中,obj.foo先运算再试行,纵然值根本未曾变化,this也不再指向obj了。那是因为那时它就退出了运行意况obj,而是在大局蒙受进行。

可以这么敞亮,在 JavaScript 引擎内部,obj和obj.foo累积在多个内部存款和储蓄器地址,简称为M1和M2。唯有obj.foo()那样调用时,是从M1调用M2,因而this指向obj。可是,上面三种情状,都以平素收取M2举行演算,然后就在大局境况举办运算结果(还是M2),由此this指向全局境遇。

上面二种景况一模二样上面包车型地铁代码。

// 情况一

(obj.foo = function () {

console.log(this);

})()

// 等同于

(function () {

console.log(this);

})()

 

// 情况二

(false || function () {

console.log(this);

})()

 

// 情况三

(1, function () {

console.log(this);

})()

只要有个别方法位于多层对象的中间,那时this只是指向当前一层的指标,而不会一连更上边的层。

var a = {

p: 'Hello',

b: {

m: function() {

console.log(this.p);

}

}

};

a.b.m() // undefined

上边代码中,a.b.m方法在a对象的第二层,该情势内部的this不是指向a,而是指向a.b。那是因为实在推行的是底下的代码。

var b = {

m: function() {

console.log(this.p);

};

 

var a = {

p: 'Hello',

b: b

};

(a.b).m() // 等同于 b.m()

假使要高达预期效果,只有写成上面那样。

var a = {

b: {

m: function() {

console.log(this.p);

},

p: 'Hello'

}

};

 

 

 

3.施用注意点

1)防止多层 this

出于this的指向是不明确的,所以切勿在函数中包涵多层的this。

var o = {

f1: function () {

console.log(this);

var f2 = function () {

console.log(this);

}();

}

}

 

o.f1()

// Object

// Window

二个解决措施是在其次层改用叁个对准外层this的变量。

var o = {

f1: function() {

console.log(this);

var that = this;

var f2 = function() {

console.log(that);

}();

}

}

 

o.f1()

// Object

// Object

2)制止数组处理措施中的this

数组的map和foreach方法,允许提供一个函数作为参数。这一个函数内部不应有运用this。

var o = {

v: 'hello',

p: [ 'a1', 'a2' ],

f: function f() {

this.p.forEach(function (item) {

console.log(this.v ' ' item);

});

}

}

 

o.f()

// undefined a1

// undefined a2

一种是是在其次层改用三个针对性外层this的变量。如上3.1

另一种方法是将this当作foreach方法的第二个参数,固定它的运作景况。

3)制止回调函数中的this

4.绑定 this 的方法

this的动态切换,就算为JavaScript创建了高大的灵活性,但也使得编制程序变得劳苦和混淆。一时,要求把this固定下来,防止出现出人意料的场所。JavaScript提供了call、apply、bind那多少个办法,来切换/固定this的针对。

1)function.prototype.call()

函数实例的call方法,能够钦赐函数内部this的对准(即函数试行时所在的成效域),然后在所钦命的功力域中,调用该函数

var obj = {};

var f = function () {

return this;

};

f() === this // true

f.call(obj) === obj // true

地点代码中,在大局遭受运转函数f时,this指向全局处境;call方法能够改造this的对准,内定this指向对象obj,然后在目的obj的作用域中运转函数f。

call方法的参数,应该是多个对象。倘若参数为空、null和undefined,则暗中认可传入全局对象。

var n = 123;

var obj = { n: 456 };

function a() {

console.log(this.n);

}

a.call() // 123

a.call(null) // 123

a.call(undefined) // 123

a.call(window) // 123

a.call(obj) // 456

地方代码中,a函数中的this关键字,如若指向全局对象,重临结果为123。倘若采取call方法将this关键字指向obj对象,再次来到结果为456。能够见到,要是call方法未有参数,只怕参数为null或undefined,则等同指向全局对象。

call方法还足以承受两个参数。

call的首先个参数正是this所要指向的十三分目的,后边的参数则是函数调用时所需的参数。

function add(a, b) {

return a b;

}

add.call(this, 1, 2) // 3

2)function.prototype.apply()

apply方法的坚守与call方法类似,也是退换this指向,然后再调用该函数。唯一的差异正是,它接受八个数组作为函数施行时的参数,使用格式如下。

func.apply(thisValue, [arg1, arg2, ...])

apply方法的第贰个参数也是this所要指向的十三分目的,借使设为null或undefined,则千篇一律内定全局对象。首个参数则是多个数组,该数组的兼具成员相继作为参数,传入原函数。原函数的参数,在call方法中必须贰个个丰裕,但是在apply方法中,必须以数组情势充足。

function f(x,y){

console.log(x y);

}

f.call(null,1,1) // 2

f.apply(null,[1,1]) // 2

风趣的使用

1)搜索数组最大因素

var a = [10, 2, 4, 15, 9];

Math.max.apply(null, a)

// 15

2)将数组的空成分变为undefined

透过apply方法,利用Array构造函数将数组的空成分产生undefined。

Array.apply(null, ["a",,"b"])

// [ 'a', undefined, 'b' ]

空成分与undefined的差别在于,数组的forEach方法会跳过空成分,可是不会跳过undefined。由此,遍历内部因素的时候,会获取分裂的结果。

var a = ['a', , 'b'];

function print(i) {

console.log(i);

}

a.forEach(print)

// a

// b

Array.apply(null, a).forEach(print)

// a

// undefined

// b

 

 

3)调换类似数组的靶子

此外,利用数组对象的slice方法,能够将一个近乎数组的靶子(比如arguments对象)转为真正的数组。

Array.prototype.slice.apply({0:1,length:1})

// [1]

Array.prototype.slice.apply({0:1})

// []

Array.prototype.slice.apply({0:1,length:2})

// [1, undefined]

Array.prototype.slice.apply({length:1})

// [undefined]

上边代码的apply方法的参数都是目的,可是回到结果都以数组,这就起到了将对象转成数组的目标。从地点代码能够看出,那几个主意起效能的前提是,被拍卖的对象必须有length属性,以及相对应的数字键。

function.prototype.bind()

bind方法用于将函数体内的this绑定到有些对象,然后回到一个新函数。

var d = new Date();

d.getTime() // 1481869925657

var print = d.getTime;

print() // Uncaught TypeError: this is not a Date object.

上面代码中,大家将d.getTime方法赋给变量print,然后调用print就报错了。那是因为getTime方法内部的this,绑定Date对象的实例,赋给变量print未来,内部的this已经不指向Date对象的实例了。

bind方法能够消除这几个标题,让log方法绑定console对象。

var print = d.getTime.bind(d);

print() // 1481869925657

地点代码中,bind方法将getTime方法内部的this绑定到d对象,这时就能够安全地将以此点子赋值给任何变量了。

bind比call方法和apply方法更进一步的是,除了绑定this以外,还足以绑定原函数的参数。

var add = function (x, y) {

return x * this.m y * this.n;

}

var obj = {

m: 2,

n: 2

};

var newAdd = add.bind(obj, 5);

newAdd(5)

// 20

地点代码中,bind方法除了绑定this对象,还将add函数的率先个参数x绑定成5,然后回来二个新函数newAdd,这些函数只要再承受二个参数y就会运维了。

若果bind方法的率先个参数是null或undefined,等于将this绑定到全局对象,函数运转时this指向顶层对象(在浏览器中为window)。

function add(x, y) {

return x y;

}

var plus5 = add.bind(null, 5);

plus5(10) // 15

bind方法有部分利用注意点。

1)每三次回到一个新函数

2)结合回调函数使用

回调函数是JavaScript最常用的形式之一,可是三个大规模的谬误是,将涵盖this的艺术直接作为回调函数。

var counter = {

count: 0,

inc: function () {

'use strict';

this.count ;

}

};

function callIt(callback) {

callback();

}

callIt(counter.inc)

// TypeError: Cannot read property 'count' of undefined

下面代码中,counter.inc方法被看做回调函数,传入了callIt,调用时在那之中间的this指向callIt运营时所在的对象,即顶层对象window,所以得不到预想结果。注意,上面包车型地铁counter.inc方法内部使用了凶横方式,在该方式下,this指向顶层对象时会报错,一般格局不会。

不留余地办法就是行使bind方法,将counter.inc绑定counter。

callIt(counter.inc.bind(counter));

counter.count // 1

var obj = {

name: '张三',

times: [1, 2, 3],

print: function () {

this.times.forEach(function (n) {

console.log(this.name);

});

}

};

 

obj.print()

// 未有别的输出

obj.print = function () {

this.times.forEach(function (n) {

console.log(this.name);

}.bind(this));

};

 

obj.print()

// 张三

// 张三

// 张三

 

本文由澳门新萄京官方网站发布于澳门新萄京赌场网址,转载请注明出处:澳门新萄京官方网站:箭头函数this深刻理解,

关键词: