与其他语言相比,函数的 this 关键字在 JavaScript 中的表现略有不同,此外,在严格模式和非严格模式之间也会有一些差别。 目录 在绝大多数情况下,函数的调用方式决定了this的值。this不能在执行期间被赋值,并且在每次函数被调用时this的值也可能会不同。ES5引入了bind方法来设置函数的this值,而不用考虑函数如何被调用的,ES2015 引入了支持this词法解析的箭头函数(它在闭合的执行环境内设置this的值)。 当前执行代码的环境对象,在非严格模式下,总是指向一个对象,在严格模式下可以是任意值 无论是否在严格模式下,在全局执行环境中(在任何函数体外部) 在函数内部, 因为下面的代码不在严格模式下,且 然而,在严格模式下, 所以,在严格模式下,如果 如果要想把 当一个函数在其主体中使用 使用 调用 当函数作为对象里的方法被调用时,它们的 下面的例子中,当 请注意,这样的行为,根本不受函数定义方式或位置的影响。在前面的例子中,我们在定义对象 箭头函数中的this 与被设置为他被创建时的环境的this 在全局代码中,它将被设置为全局对象 如果将 就是不管你咋调用咋折腾都是没有用的,this是不会改变的,他只会和定义时候的环境有关。 无论如何, 看下边的例子会有一些启发 原型链中的 对于在对象原型链上某处定义的方法,同样的概念也适用。如果该方法存在于一个对象的原型链上,那么 在这个例子中,对象 再次,相同的概念也适用于当函数在一个 当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。 在刚刚的例子中( 当函数被用作事件处理函数时,它的 当代码被内联事件调用时,它的 上面的 alert 会显示 在这种情况下,没有设置内部函数的 文章参考: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
1. 全局环境
this
都指向全局对象。
// 在浏览器中, window 对象同时也是全局对象: console.log(this === window); // true a = 37; console.log(window.a); // 37 this.b = "jhj"; console.log(window.b) // "jhj" console.log(b) // "jhj"
2. 函数(运行内)环境
this
的值取决于函数被调用的方式。(重点)this
的值不是由该调用设置的,所以 this
的值默认指向全局对象。
function f1(){ return this; } //在浏览器中: f1() === window; //在浏览器中,全局对象是window //在Node中: f1() === global;
this
将保持他进入执行环境时的值,所以下面的this
将会默认为undefined
。
function f2(){ "use strict"; // 这里是严格模式 return this; } f2() === undefined; // true
this
没有被执行环境(execution context)定义,那它将保持为 undefined
。3.call
和 apply
this
的值从一个环境传到另一个,就要用 call
和 apply
方法。
// 将一个对象作为call和apply的第一个参数,this会被绑定到这个对象。 var obj = {a: 'Custom'}; // 这个属性是在global对象定义的。 var a = 'Global'; function whatsThis(arg) { return this.a; // this的值取决于函数的调用方式 } whatsThis(); // 'Global' whatsThis.call(obj); // 'Custom' whatsThis.apply(obj); // 'Custom'
this
关键字时,可以通过使用函数继承自Function.prototype
的 call
和 apply
方法将 this
值绑定到调用中的特定对象。
function add(c, d) { return this.a + this.b + c + d; } var o = {a: 1, b: 3}; // 第一个参数是作为‘this’使用的对象 // 后续参数作为参数传递给函数调用 add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 // 第一个参数也是作为‘this’使用的对象 // 第二个参数是一个数组,数组里的元素用作函数调用中的参数 add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34
call
和 apply
函数的时候要注意,如果传递给 this
的值不是一个对象,JavaScript 会尝试使用内部 ToObject
操作将其转换为对象。因此,如果传递的值是一个原始值比如 7
或 'foo'
,那么就会使用相关构造函数将它转换为对象,所以原始值 7
会被转换为对象,像 new Number(7)
这样,而字符串 'foo'
转化成 new String('foo')
这样,例如:
function bar() { console.log(Object.prototype.toString.call(this)); } //原始值 7 被隐式转换为对象 bar.call(7); // [object Number] bar.call('foo'); // [object String]
4. bind方法
bind
方法会返回函数的拷贝值,但带有绑定的上下文! 它不会立即执行!!!f.bind(someObject)
会创建一个与f
具有相同函数体和作用域的函数,但是在这个新函数中,this
将永久地被绑定到了bind
的第一个参数,无论这个函数是如何被调用的,只生效一次
function f(){ return this.a; } var g = f.bind({a:"jhj"}); console.log(g()); // jhj var h = g.bind({a:'yoo'}); // bind只生效一次! console.log(h()); // jhj var o = {a:37, f:f, g:g, h:h}; console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, jhj, jhj
5. 作为对象的方法
this
是调用该函数的对象。o.f()
被调用时,函数内的this
将绑定到o
对象。
var o = { prop: 37, f: function() { return this.prop; } }; console.log(o.f()); // 37
o
的同时,将函数内联定义为成员 f
。但是,我们也可以先定义函数,然后再将其附属到o.f
。这样做会导致相同的行为:
var o = {prop: 37}; function independent() { return this.prop; } o.f = independent; console.log(o.f()); // 37
6. 箭头函数的this
var globalObject = this; var foo = (() => this); console.log(foo() === globalObject); // true
this
传递给call
、bind
、或者apply
来调用箭头函数,它将被忽略。不过你仍然可以为调用添加参数,不过第一个参数(thisArg
)应该设置为null
。
var globalObject = this; var foo = (() => this); console.log(foo() === globalObject); // true // 作为对象的一个方法调用 var obj = {foo: foo}; console.log(obj.foo() === globalObject); // true // 尝试使用call来设定this console.log(foo.call(obj) === globalObject); // true // 尝试使用bind来设定this foo = foo.bind(obj); console.log(foo() === globalObject); // true
foo
的 this
被设置为他被创建时的环境(在上面的例子中,就是全局对象)。这同样适用于在其他函数内创建的箭头函数:这些箭头函数的this
被设置为封闭的词法环境的。
// 创建一个含有bar方法的obj对象, // bar返回一个函数, // 这个函数返回this, // 这个返回的函数是以箭头函数创建的, // 所以它的this被永久绑定到了它外层函数的this。 // bar的值可以在调用中设置,这反过来又设置了返回函数的值。 var obj = { bar: function() { var x = (() => this); return x; } }; // 作为obj对象的一个方法来调用bar,把它的this绑定到obj。 // 将返回的函数的引用赋值给fn。 var fn = obj.bar(); // 直接调用fn而不设置this, // 通常(即不使用箭头函数的情况)默认为全局对象 // 若在严格模式则为undefined console.log(fn() === obj); // true // 但是注意,如果你只是引用obj的方法, // 而没有调用它 var fn2 = obj.bar; // 那么调用箭头函数后,this指向window,因为它从 bar 继承了this。 console.log(fn2()() == window); // true
7. 原型链上的this
this
this
指向的是调用这个方法的对象,就像该方法在对象上一样。
var o = { f: function() { return this.a + this.b; } }; var p = Object.create(o); p.a = 1; p.b = 4; console.log(p.f()); // 5
p
没有属于它自己的f
属性,它的f属性继承自它的原型。虽然在对 f
的查找过程中,最终是在 o
中找到 f
属性的,这并没有关系;查找过程首先从 p.f
的引用开始,所以函数中的 this
指向p
。也就是说,因为f
是作为p
的方法调用的,所以它的this
指向了p
。这是 JavaScript 的原型继承中的一个有趣的特性。8. getter 与 setter 中的
this
getter
或者 setter
中被调用。用作 getter
或 setter
的函数都会把 this
绑定到设置或获取属性的对象。
function sum() { return this.a + this.b + this.c; } var o = { a: 1, b: 2, c: 3, get average() { return (this.a + this.b + this.c) / 3; } }; Object.defineProperty(o, 'sum', { get: sum, enumerable: true, configurable: true}); console.log(o.average, o.sum); // logs 2, 6
9. 构造函数中的this
/* * 构造函数这样工作: * * function MyConstructor(){ * // 函数实体写在这里 * // 根据需要在this上创建属性,然后赋值给它们,比如: * this.fum = "nom"; * // 等等... * * // 如果函数具有返回对象的return语句, * // 则该对象将是 new 表达式的结果。 * // 否则,表达式的结果是当前绑定到 this 的对象。 * //(即通常看到的常见情况)。 * } */ function C(){ this.a = 37; } var o = new C(); console.log(o.a); // logs 37 function C2(){ this.a = 37; return {a:38}; } o = new C2(); console.log(o.a); // logs 38
C2
),因为在调用构造函数的过程中,手动的设置了返回对象,与this
绑定的默认对象被丢弃了。(这基本上使得语句 “this.a = 37;
”成了“僵尸”代码,实际上并不是真正的“僵尸”,这条语句执行了,但是对于外部没有任何影响,因此完全可以忽略它)。10. DOM事件处理函数的this
this
指向触发事件的元素(一些浏览器在使用非addEventListener
的函数动态添加监听函数时不遵守这个约定)。
// 被调用时,将关联的元素变成蓝色 function bluify(e){ console.log(this === e.currentTarget); // 总是 true // 当 currentTarget 和 target 是同一个对象时为 true console.log(this === e.target); this.style.backgroundColor = '#A5D9F3'; } // 获取文档中的所有元素的列表 var elements = document.getElementsByTagName('*'); // 将bluify作为元素的点击监听函数,当元素被点击时,就会变成蓝色 for(var i=0 ; i<elements.length ; i++){ elements[i].addEventListener('click', bluify, false); }
this
指向监听器所在的DOM元素:
<button onclick="alert(this.tagName.toLowerCase());"> Show this </button>
button
。注意只有外层代码中的this
是这样设置的:
<button onclick="alert((function(){return this})());"> Show inner this </button>
this
,所以它指向 global/window 对象(即非严格模式下调用的函数未设置this
时指向的默认对象)。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算