全局对象的 this 指向 window 对象(所在作用域?)
var a = 1000;
var obj = {
a: 1,
b: this.a+1
}
//普通对象 obj 没有 this,里面访问的 this指向 window 对象。
console.log(obj.b);//1001
如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window
//直接打印
console.log(this) //window
//function声明函数
function bar () {console.log(this)}
bar() //window
//function声明函数赋给变量
var bar = function () {console.log(this)}
bar() //window
//自执行函数
(function () {console.log(this)})(); //window
函数中调用另一个函数
function foo() {
console.log(this); // window
}
function bar() {
console.log(this); // window
// 直接调用
foo();
}
// 直接调用
bar();
全局函数执行 this 指向 window
function fun(){
console.log(this === window) //true
}
又
var name = "William";
function test(){
var name = "Lisi";
let a = {
name: this.name
}
console.log(a.name);
}
test();//William
this 永远指向最后调用它的那个对象,适用于非箭头函数的调用
(隐式绑定:函数还可以作为某个对象的方法调用,这时this就指这个上级对象)
var a = 1000;
function fun(){
var obj = {
a: 1,
c: this.a + 2
}
return obj.c;
}
//fun 函数执行的时候内部 this 指向 window
console.log(fun());//1002
let obj = {
name: "William",
say: function(){
console.log(this.name);
}
}
//say 函数在执行的时候,是被 obj 对象调用的,所以指向的是 obj 对象,this.name 访问的是 obj.name
obj.say();//William
var o = {
a:10,
b:{
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();//undefined
分析:这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
分析:结合第七点看,同时,记住,this永远指向的是最后调用它的对象,虽然fn是对象b的方法,但是fn赋值给j时候并没有执行,所以最终指向window
var obj = {
number: 1,
getOwnNumber: function () {
var number = 2;
return this.number;
},
getNumber: function () {
var number = 3;
return function () {
var number = 4;
return this.number;
};
}
}
console.log(obj.getOwnNumber());//1
console.log(obj.getNumber()());//undefined
分析:
obj.getNumber()运行结果是一个匿名函数,然后再执行匿名函数
过程拆分为:
var fun = obj.getNumber() // 返回一个匿名函数
fun();
所以此处this指向window对象
const a = 1000;
function f1(a, b){
this.a = a;
this.b = b;
console.log(this===window);
}
f1(); //true
const f = new f1(1,2); //false
console.log(f.a);//1
分析:
new 操作符做了什么?
1、首先内部创建了一个空对象 obj
2、将新对象的__proto__指向构造函数的 prototype 对象
3、将构造函数的作用域赋值给新的对象(也就是this 指向新对象)
4、执行构造函数中的代码(为这个新对象添加属性)
5、返回apply执行的结果或者返回对象
//模拟 new 代码
function create(fn, ...rest){
const obj = Object.create(fn.prototype);
const result = fn.apply(obj, rest);
if(typeof result === "object"){
return result;
}else{
return obj;
}
}
再列举一些特殊情况:
function fn()
{
this.user = 'xxx';
return {};
}
var a = new fn();
console.log(a);//{}
//new过程遇到return一个对象,此时this指向为返回的对象
//实质还是他调用的对象
console.log(a.user); //undefined
拓展:
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
function fn()
{
this.user = 'sweet';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = 'sweet';
return 1;
}
var a = new fn;
console.log(a.user); //sweet
function fn()
{
this.user = 'sweet';
return undefined;
}
var a = new fn;
console.log(a.user); //sweet
function fn()
{
this.user = 'sweet';
return null;
}
var a = new fn;
console.log(a.user); //sweet
apply call bind 可以改变 this 指向,准确的说是改变非箭头函数的 this 指向。
let obj = {
name: "William",
say: function(){
console.log(this.name);
}
}
obj.say();//William
obj.say.apply({name: "Ben"})//Ben
箭头函数的 this 在定义时确定。
箭头函数 this 指向:箭头函数没有自己的 this,看其外层的是否有函数,如果有,外层函数的 this 就是内部箭头函数的 this,如果没有,则 this 是 window。
箭头函数的特性:
window.color = "red";
let color = "green";
// var color = "black";
let obj = {
color: "blue"
};
let sayColor = () => {
return this.color;
};
console.log(sayColor.apply(obj));//red
分析:
1、sayColor 是一个箭头函数,applay 是不起作用的,所以函数里面的this 没有被改变。这里箭头函数里面的 this 按照定义的时候 this 的指向的。定义 sayColor 的时候 this 指向全局 window。
2、this.color 指的是 window.color。又 let const 定义的变量并不会加载到 window 上面的。所以 let color并不会改变 window.color的值
拓展
const obj = {
sayThis: () => {
console.log(this);
}
};
obj.sayThis(); // window 因为 JavaScript 没有块作用域,所以在定义 sayThis 的时候,里面的 this 就绑到 window 上去了
const globalSay = obj.sayThis;
globalSay(); // window 浏览器中的 global 对象
匿名函数的 this 永远指向 window ,没有变量指向匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window。
var name = "The window";
var object = {
name: 'My Object',
//obj.getNameFunc 指向了后面的匿名函数
getNameFunc: function () {
console.log(this);//object
return function () {
return this.name;
}
},
getName: function () {
//此时,箭头函数的this指向就是当前所在环境了,不像上面没有指向的匿名函数会都指向window
return ()=>{
return this.name;
}
}
}
console.log(object.getNameFunc()());//The window
console.log(object.getName()());//My Object