工作原理以及注意事项,的运行机制及爬坑指南永利澳门游戏网站:

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)

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

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();

  在实函数中,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

  3、传递到eval(卡塔尔国中的字符串:要是eval(卡塔尔(英语:State of Qatar)是被一向调用的,this
指的是时下指标;倘诺eval(卡塔尔是被直接调用的,this 正是指全局对象。

陷阱: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(卡塔尔(英语:State of Qatar)的不等。
有两种格局能够改正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(卡塔尔(英语:State of Qatar)。
使用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);
}

复制代码 代码如下:

与this相关的圈套

有四个你要求领悟的与this相关的骗局。请留神,在各样情形下,凶暴格局更安全,因为this在平凡函数中为undefined,并且会在现身难题时告诫。

  4.3 隐藏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 收藏
评论

永利澳门游戏网站 1

JS中new
操作的兑现原理大约如下边包车型大巴代码所示(更标准的贯彻请看这里,这么些达成也比较复杂一些):

this 在函数中

那是最常用的 this 使用方法,函数通过扮演二种分化的剧中人物来表示 JavaScript
中的全部可调用构造体:

  • 日常说来函数(this 在非严刻形式下为全局对象,在从严形式下为undefined)
  • 布局函数(this 指向新创立的实例)
  • 办法(this 是指方法调用的收信人)

在函数中,this 平日被以为是贰个外加的,隐含的参数。

  在浏览器中,功能域就是大局成效域,this
指的便是其风度翩翩全局对象(就疑似window):

骗局:不得法地领到方法

即使获得情势的值(不是调用它),则能够将该措施转变为函数。
调用该值将变成函数调用,并非方式调用。
当将艺术作为函数或方法调用的参数字传送递时,可能会产生这种提取。
实际例子包涵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。

复制代码 代码如下:

Rauschmayer](卡塔尔(英语:State of Qatar)   译文出处:[众成翻译

woolll]()   

永利澳门游戏网站 2

在 JavaScript 中,this 那个奇特的变量是相对相比复杂的,因为 this
不止用在面向对象遇到中,在别的任哪个地方方也是可用的。 本篇博文中会解释
this 是怎么样行事的以至利用中也许形成难点的地点,最终奉上最棒施行。

为了越来越好驾驭 this,将 this 使用的场景分成三类:

  • 在函数内部 this 三个附加的,日常是包涵的参数。
  • 在函数外界(顶尖效用域中): 那指的是浏览器中的全局对象可能Node.js 中三个模块的出口。
  • 在传递给eval(卡塔尔国的字符串中: eval(卡塔尔 或许得到 this
    当前值值,或许将其安装为全局对象,决计于 this
    是一贯调用照旧直接调用。

大家来探视各种项目。

  你能够经过new 将二个函数充当一个协会器来使用。new
操作成立了叁个新的对象,并将这么些目的通过this 传入布局器中。

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

    实函数
    构造器
    方法

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

2018/03/14 · JavaScript
· this

原著出处: [Dr. Axel

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

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

在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;
}

复制代码 代码如下:

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’卡塔尔(英语:State of Qatar) ===
window卡塔尔(英语:State of Qatar); // 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(卡塔尔(英语:State of Qatar);

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();

复制代码 代码如下:

2、成效域中的this

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

复制代码 代码如下:

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

复制代码 代码如下:

Strict模式:this 的值是undefined。

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)

但是假如运用的是strict方式,那您要么会博得警告(this===undefined):

// `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个和this
有关的牢笼。要小心,在上边包车型地铁事例中,使用Strict情势(strict
mode卡塔尔(قطر‎都能抓牢代码的安全性。由于在实函数中,this
的值是undefined,当现身难点的时候,你会获取警告。

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

1.3  方法中的this

4.2 不恰本地接纳方法

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

  1、that=this,将this 赋值到叁个变量上,那样就把this
显性地显示出来了(除了that,self
也是个很遍布的用来存放this的变量名),之后就动用非常变量:

  1.1  在实函数中的this

复制代码 代码如下:

bind(卡塔尔(英语:State of Qatar)再次创下办了三个老是能将this的值设置为counter 的函数。

3、eval()中的this

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

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

上面包车型地铁事例里函数中的this.name 不可能动用,因为函数的this
的值是undefined,那和章程loop(卡塔尔(英语:State of Qatar)中的this
不雷同。下边提供了二种思路来解决那么些标题:

2、bind(卡塔尔。使用bind(卡塔尔来成立一个函数,那些函数的this
总是存有你想要传递的值(上边那个例子中,方法的this):

 4、与this有关的圈套

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

复制代码 代码如下:

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 = {
    method: function () {
        console.log(this === obj); // true
    }
}
obj.method();

自家不爱好有个别API把this 充当实函数的叁个叠合参数:

复制代码 代码如下:

1.2  布局器中的this

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

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

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

在Node.js中,你平凡都以在module中实践函数的。由此,超级效率域是个异常特别的模块成效域(module
scope):

发表评论

电子邮件地址不会被公开。 必填项已用*标注