1.this
的值取决于函数被调用的方式 正常调用指向window 谁调用就指向谁
var objData = {a: 'custom'};
// 这个属性是在global对象定义的
var a = 'global';
function whatsThis() {
return this.a; // this的值取决于函数的调用方式
}
whatsThis(); // 输出 "global"
2.使用call apply方法可以强制改变this指向
let objData = {a: 'custom'};
// 这个属性是在global对象定义的
let a = 'global';
function whatsThis () {
return this.a
}
whatsThis.call(objData); // 输出 "custom"
3.ES5中加了 bind 函数名.bind() 将会创建一个与该函数体相同的新函数 这个新函数 不论在哪里调用 this的指向都会指向bind的第一个参数 被永久绑定 这个新的函数体只会被绑定一次
function whatsThis () {
return this.a;
}
let pointThis = whatsThis.bind({a: 'point'});
pointThis(); // 输出 point
let bindThis = pointThis.bind({a: 'bind'});
bindThis(); // 输出 point
let againBind = whatsThis.bind({a: 'again'});
againBind(); // 输出 again
4.箭头函数内的this 一旦被调用 就永久指向 无法修改 如果只是引用 没有调用 那么调用箭头函数后,this指向window
var a = '全局a';
let foo = (() => this.a);
foo(); // 全局a
let a = '全局a';
let foo = (() => this.a);
foo(); // undefined
let objData = {
a: 'objData中的a',
foo:foo
}
objData.foo(); // 全局a
let secondData = {a: 'secondData中的a'}
objData.foo.call(secondData); // 全局a
objData.foo.bind({a: 'bind中的a'});
objData.foo() // 全局a
5.如果一个构造函数具有返回对象的return语句和绑定this的对象 则结果是返回的return 否则 是this 2个都有 返回return 没有return 只有this 则返回this
function foo() {
this.a = 'foo'
}
let secondFoo = new foo();
secondFoo.a // foo
function foo() {
this.a = 'foo'
return {a: 'foo中的第二个a'}
}
let secondFoo = new foo();
secondFoo.a // foo中的第二个a
6.whatsThis中的this分别指向obj和全局 之所以输出内容是whatsThis中的a 因为就近先查找到了a的值
var obj = {a: 'custom'};
var a = 'global';
function whatsThis () {
this.a = 'whatsThis中的a';
return this.a;
}
whatsThis.call(obj); // 输出 whatsThis中的a
var obj = {a: 'custom'};
var a = 'global';
function whatsThis () {
this.a = 'whatsThis中的a';
return this.a;
}
whatsThis(); // 输出 whatsThis中的a
7.在严格模式下,如果 this
没有被执行环境定义,那它将保持为 undefined
function whatsThis() {
"use strict"; // 这里是严格模式
return this;
}
whatsThis(); // undefined
function whatsThis() {
return this;
}
whatsThis(); // Window
8.匿名函数的执行环境具有全局性,因此其this对象通常指向window。
var name = 'The Window';
var object = {
name: 'My Object',
getName: function(){
return function(){
return this.name
}
}
}
console.log(object.getName()()); // 'The Window'
为什么上面例子中返回的是全局的name呢?
是因为每个函数在被调用时都会自动取得2个特殊变量:this和arguments。内部函数在搜索这2个变量时,只会搜索到其活动对象为止。因此永远不可能直接访问外部函数中的这2个变量。
当然如果想访问object的name属性,可以把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了。
var name = 'The Window';
var object = {
name: 'My Object',
getName: function(){
var that = this;
return function(){
return that.name
}
}
}
console.log(object.getName()()); // 'My Object'
如下写法也可以直接返回object中的name
var name = 'The Window';
var object = {
name: 'My Object',
getName: function(){
return that.name;
}
}
console.log(object.getName()); // 'My Object'
console.log(object.getName)(); // 'My Object'
console.log(object.getName = object.getName)(); // 'The window', 在非严格模式下
上面打印的三组内容,第一行代码返回的是'My Object',因为This.name就是object.name
第二行代码虽然在调用前加了括号,就好像只是在引用一个函数,但this的值得到了维持。因为object.getName和(object.getName)的定义是相同的。
第三行代码先执行了一条赋值语句,然后再调用赋值后的结果。因为这个赋值表达式的值是函数本身,所以this的值不能得到维持。结果就返回了'The window'